When there is no MME-UE Context, going to cleanup without setting
s6a_message could cause a segmentation fault.
We fixed the problem by moving the location of setting s6a_message
to before cleanup.
The UPF is sending Session Report Request after the Session was Deleted,
when the Gy interface is active.
UPF is sending PFCP session report request after the session has been deleted
when the Gy interface is active. This is because some of the timers related to
the report are not deleted when the session is deleted.
We have fixed it to delete all the timers in the session
when the SESSION is deleted.
Problems with Purge-UE-Request/Answer can occur in the following situations
1. Attach Request
2. Authentication request
3. Authentication reject
4. UEContextReleaseCommand
5. UEContextReleaseComplete
6. Purge-UE-Request
7. Attach Request
8. Purge-UE-Answer
9. (UE Context Remove)
To resolve this issue, we have changed to delete the UE-Context
via mme_ue_remove() immediately upon receiving UEContextReleaseComplete()
without calling mme_s6a_send_pur().
1. Reachable assertion in ogs_nas_5gmm_decode
Location: lib/nas/5gs/decoder.c:4445
```c
int ogs_nas_5gmm_decode(ogs_nas_5gs_message_t *message, ogs_pkbuf_t *pkbuf)
{
int size = 0;
int decoded = 0;
ogs_assert(pkbuf);
ogs_assert(pkbuf->data);
ogs_assert(pkbuf->len);
```
When a NAS payload is received over `src/amf/context.c:1675`NGAP that has no data, the ogs_assert(pkbuf->len) assertion will be triggered.
2.Reachable assertion in ogs_nas_emm_decode
```
int ogs_nas_emm_decode(ogs_nas_eps_message_t *message, ogs_pkbuf_t *pkbuf)
{
int size = 0;
int decoded = 0;
ogs_assert(pkbuf);
ogs_assert(pkbuf->data);
ogs_assert(pkbuf->len);
```
Nearly identical to (1), but for LTE.
3. Reachable assertion in nas_eps_send_emm_to_esm
```
int nas_eps_send_emm_to_esm(mme_ue_t *mme_ue,
ogs_nas_esm_message_container_t *esm_message_container)
{
int rv;
ogs_pkbuf_t *esmbuf = NULL;
if (!mme_ue_cycle(mme_ue)) {
ogs_error("UE(mme-ue) context has already been removed");
return OGS_NOTFOUND;
}
ogs_assert(esm_message_container);
ogs_assert(esm_message_container->length);
```
The ESM message payload may be 0-length, as the length is determined by a field in the NAS payload (which can be chosen arbitrarily by an attacker). This leads to the length assertion above being triggered.
5. Reachable assertion and incorrect hash calculation in ogs_kdf_hash_mme
```
void ogs_kdf_hash_mme(const uint8_t *message, uint8_t message_len, uint8_t *hash_mme)
{
uint8_t key[32];
uint8_t output[OGS_SHA256_DIGEST_SIZE];
ogs_assert(message);
ogs_assert(message_len);
ogs_assert(hash_mme);
memset(key, 0, 32);
ogs_hmac_sha256(key, 32, message, message_len,
output, OGS_SHA256_DIGEST_SIZE);
memcpy(hash_mme, output+24, OGS_HASH_MME_LEN);
}
```
When handling NAS attach requests or TAU requests, the ogs_kdf_hash_mme function is passed the NAS payload. However, the length field is represented as an unsigned 8-bit integer, which the passed length of the packet may overflow. This leads to the passed value being truncated.
When the passed value is a multiple of 256, the above assertion (ogs_assert(message_len)) is triggered. Otherwise, the hash is computed on only the first n bits of the message (where n = actual_message_len % 256).
There is an issue with SESSION RELEASE not working properly
depending on the PDU session release complete order
in the PDUSessionResourceReleaseResponse.
If the AMF receives PDUSessionResourceReleaseResponse
followed by PDU session release complete, it works correctly.
However, if it receives PDU session release complete
followed by PDUSessionResourceReleaseResponse, it does not work correctly
and sends an Error Indication to the UE/gNB.
To fix this issue, we added pdu_session_release_complete_received and
pdu_session_resource_release_response_received to the content
so that CLEAR_SM_CONTEXT_REF() is executed when both are received.
Because a race condition can occur between S6A Diameter and S1AP message,
the following error handling code has been added.
1. InitialUEMessage + Attach Request + PDN Connectivity request
2. Authentication-Information-Request/Authentication-Information-Answer
3. Authentication Request/Response
4. Security-mode command/complete
5. Update-Location-Request/Update-Location-Answer
6. Detach request/accept
In the ULR/ULA process in step 6, the PDN Connectivity request is
pushed to the queue as an ESM_MESSAGE because the NAS-Type is still
an Attach Request.
See the code below in 'mme-s6a-handler.c' for where the queue is pushed.
if (mme_ue->nas_eps.type == MME_EPS_TYPE_ATTACH_REQUEST) {
rv = nas_eps_send_emm_to_esm(mme_ue,
&mme_ue->pdn_connectivity_request);
if (rv != OGS_OK) {
ogs_error("nas_eps_send_emm_to_esm() failed");
return OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED;
}
} else if (mme_ue->nas_eps.type == MME_EPS_TYPE_TAU_REQUEST) {
r = nas_eps_send_tau_accept(mme_ue,
S1AP_ProcedureCode_id_InitialContextSetup);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
} else {
ogs_error("Invalid Type[%d]", mme_ue->nas_eps.type);
return OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED;
}
If you perform step 7 Detach request/accept here,
the NAS-Type becomes Detach Request and the EMM state changes
to emm_state_de_registered().
Since the PDN, which is an ESM message that was previously queued,
should not be processed in de_registered, the message is ignored
through error handling below.
Otherwise, MME will crash because there is no active bearer
in the initial_context_setup_request build process.
See the code below in 's1ap-build.c' for where the crash occurs.
ogs_list_for_each(&mme_ue->sess_list, sess) {
ogs_list_for_each(&sess->bearer_list, bearer) {
...
if (mme_ue->nas_eps.type == MME_EPS_TYPE_ATTACH_REQUEST) {
} else if (OGS_FSM_CHECK(&bearer->sm, esm_state_inactive)) {
ogs_warn("No active EPS bearer [%d]", bearer->ebi);
ogs_warn(" IMSI[%s] NAS-EPS Type[%d] "
"ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]",
mme_ue->imsi_bcd, mme_ue->nas_eps.type,
enb_ue->enb_ue_s1ap_id, enb_ue->mme_ue_s1ap_id);
continue;
}
...
}
}
As mentioned in the sgwu.yaml configuration file, it is possible to configure multiple addresses with different source_interface values for the gtpu interface.
Following the this section, I defined two addresses, one with source_interface set to 0 and another with source_interface set to 1. My expectation was to see different addresses for the two PDRs in the Session Establishment Response message during session establishment. However, both addresses were the same, and it was the address I had set for source_interface = 0.
When I looked into the code, I found the reason for the issue. In the lib/pfcp/context.c file, on line 1185, the function that determines the address is called as follows:
...
} else {
ogs_gtpu_resource_t *resource = NULL;
resource = ogs_pfcp_find_gtpu_resource(
&ogs_gtp_self()->gtpu_resource_list,
pdr->dnn, OGS_PFCP_INTERFACE_ACCESS);
if (resource) {
...
In the last parameter of this function, a constant value, OGS_PFCP_INTERFACE_ACCESS, is used. This causes every PDR with any source_interface to be considered as "access," and the value 0 is used for its interface.
I replaced the value with pdr->src_if, and the bug was resolved.
A race condition can occur in the following situations.
In conclusion, we can use this situation to determine
whether or not the UE Context has been removed and avoiding a crash.
For example, suppose a UE Context is removed in the followings.
1. Attach Request
2. Authentication-Information-Request
3. Authentication-Information-Answer
4. Authentication Request
5. Authentication Response(MAC Failed)
6. Authentication Reject
7. UEContextReleaseCommand
8. UEContextReleaseComplete
The MME then sends a Purge-UE-request to the HSS and deletes
the UE context as soon as it receives a Purge-UE-Answer.
Suppose an Attach Request is received from the same UE
between Purge-UE-Request/Answer, then the MME and HSS start
the Authentication-Information-Request/Answer process.
This can lead to the following situations.
1. Purge-UE-Request
2. Attach Request
3. Authentication-Information-Request
4. Purge-UE-Answer
5. [UE Context Removed]
6. Authentication-Information-Answer
Since the UE Context has already been deleted
when the Authentication-Information-Answer is received,
it cannot be processed properly.
Therefore, mme_ue_cycle() is used to check
whether the UE Context has been deleted and
decide whether to process or
ignore the Authentication-Information-Answer as shown below.
Instead of checking if caller memset'ted the structure to zero, memset
it inside the function regardless.
There is no added benefit of a memset() + memcmp() to check if caller
cleared the structure used for outputing data from the database.
In an Inter-RAT setup a UE could perform a TAU coming from a 2G/3G network.
In that case the UE/MS is unknown to the MME and it should request the
SGSN context (MM, PDP) from the old SGSN. This is done through the following
GTPv1C message exchange on the Gn interface of SGSN and MME:
SGSN <- MME: SGSN Context Request
SGSN -> MME: SGSN Context Response
SGSN <- MME: SGSN Context Acknowledge
Diagram with full set of steps can be found at 3GPP TS 23.401 D.3.6.
This commit doesn't aim to be a complete implementation of the mentioned
procedure, since it's quite a complex one, with lots of fields and logic
required. This so far only implements in general the minimally
successful case by filling as much as possible the required set of
fields.
This will allow for a base onto which do incremental improvements and
fixes while testing against UEs and SGSNs (such as osmo-sgsn, which
doesn't yet support this procedure but will potentially earn it soon).
The reverse direction, aka UE issuing cell reselection 4G->2G was
already implemented (same as here, initial non-complete implementation)
in open5gs-mmed in commit 3d693da73e.
Related: https://osmocom.org/issues/6294
Within the PathSwitchRequest packet,
the E-RABToBeSwitchedDLList has two bearers.
If the E-RAB-ID of both bearers is 5, the MME's list memory is destroyed
and the MME crashes. To fix this issue, we modified the code so that
the MME can work correctly with invalid S1AP messages.
This will be useful for other procedures where only the RAI is known,
but not the specific CI. This is the case of idle mobility from Gb or Iu
to EUTRAN, where MME needs to request contexts based on the RAI mapped
in the GUTI obtained from the UE during TAU.
This also makes the config more resilient in RIM scenario, where an SGSN
can be picked now even if CI doesn't match, instead of failing or faling
back to the default route SGSN.
While they were continuing their fuzzy testing and developing PacketRusher, an unusual issue with the AMF was observed. The problem arises when a single Ethernet frame containing three bundled SCTP chunks is sent. This behavior is reproduced with PacketRusher when attempting to concurrently register two UEs with the same MSIN.
The expected behavior is that the PDU Session Establishment Accept is sent inside a DownlinkNASTransport to RAN UE NGAP ID 1. However, it is actually sent inside an InitialContextSetupRequest to RAN UE NGAP ID 2. The MAC of this NAS message is invalid for the Security Context of RAN UE NGAP ID 2 (probably valid for RAN UE NGAP ID 1)
../lib/core/ogs-list.h:62:24: warning: invalid conversion from 'void*' to 'ogs_list_t*' {aka 'ogs_list_s*'} [-fpermissive]
../lib/core/ogs-rbtree.h:79:32: warning: invalid conversion from 'const void*' to 'const ogs_rbnode_t*' {aka 'const ogs_rbnode_s*'} [-fpermissive]
[SBI] Fix compiler error - possible uninitialized variable
[SCP] Fix compiler error - Error: this condition has identical branches
In case of additional compiler warnings turned on, the compiler warns
about potentially unused variables. Fix those issues.
Both types are defined under lib/proto/type.h, and the conversion
function is used in several different protocols, so let's better move it
to generic lib/proto/conv.h and remove the "gtp2" prefix.
The assert is checking for sess->session->name, but afterwards there's a
check to skip ses->session not being null, which means the assert can
crash while dereferencing sess->session.
I've resolved an issue where sending continuous
'PDU Session Release Request' message to the same session,
when more than two sessions were created, was causing an SMF crash.
For your reference, this problem did not occur
when only one session was created.
In an Inter-RAT setup a UE could perform a RAU coming from a 4G network.
In that case the UE/MS is unknown to the SGSN and it should request the
SGSN context (MM, PDP) from the MME. This is done through the following
GTPv1C message exchange on the Gn interface of SGSN and MME:
SGSN -> MME: SGSN Context Request
SGSN <- MME: SGSN Context Response
SGSN -> MME: SGSN Context Acknowledge
This commit doesn't aim to be a complete implementation of the mentioned
procedure, since it's quite a complex one, with lots of fields and logic
required. This so far only implements in general the minimally
successful case by filling as much as possible the required set of
fields.
This will allow for a base onto which do incremental improvements and
fixes while testing against UEs and SGSNs (such as osmo-sgsn, which
doesn't yet support this procedure but will potentially earn it soon).
This commit doesn't implement the reverse direction, aka UE issuing cell
reselection 2G->4G. Initial support for this scenario will hopefully be
added soon as a follow-up patch, similar to this one.
Related: https://osmocom.org/issues/6294
In an Inter-RAT setup a UE could perform a RAU coming from a 4G network.
In that case the UE/MS is unknown to the SGSN and it should request the
SGSN context (MM, PDP) from the MME. This is done through the following
GTPv1C message exchange on the Gn interface of SGSN and MME:
SGSN -> MME: SGSN Context Request
SGSN <- MME: SGSN Context Response
SGSN -> MME: SGSN Context Acknowledge
This commit doesn't aim to be a complete implementation of the mentioned
procedure, since it's quite a complex one, with lots of fields and logic
required. This so far only implements in general the minimally
successful case by filling as much as possible the required set of
fields.
This will allow for a base onto which do incremental improvements and
fixes while testing against UEs and SGSNs (such as osmo-sgsn, which
doesn't yet support this procedure but will potentially earn it soon).
This commit doesn't implement the reverse direction, aka UE issuing cell
reselection 2G->4G. Initial support for this scenario will hopefully be
added soon as a follow-up patch, similar to this one.
Related: https://osmocom.org/issues/6294
This information will be required by the Gn interface in MME when
answering an SGSN with an "SGSN Context Response" message during MS cell
reselection EUTRAN->GERAN.
* [AMF/MME] UEContextReleaseCommand in Integrity (#2786)
Modified not to send UEContextReleaseCommand in Integrity Unprotected
NAS message such like Registration or Service request.
* [AMF/MME] UEContextReleaseCommand after Interity Protected (#2786)
Modified not to send UEContextReleaseCommand in Integrity Unprotected
NAS message such like Registration or Service request.
Allow network operators to omit the time zone in the 4G EMM Information
and 5G Configuration Update. This is useful for better compatibility
with some UEs.
The parameter is optional according to:
* 4G: 3GPP TS 24.301 Table 8.2.13.1
* 5G: 3GPP TS 24.501 Table 8.2.19.1.1
Bug:
In case that AMF does not have subscription data for the UE,
PDU session remains unreleased after implicit de-registeration.
The exact test case:
- UE registered (integrity protection applied)
- UE deregistered (Nudm_SDM_Unsubscribe, Nudm_UECM_Registration (purgeFlag))
- UE registered, PDU session activated
UE data are still stored in AMF. So if integrity protected applies,
the steps 4 - 14 [ETSI TS 123 502 V16.7.0](https://www.etsi.org/deliver/etsi_ts/123500_123599/123502/16.07.00_60/ts_123502v160700p.pdf) are skipped.
Only AM Policy Association Establishment is performed.
- UE is moved out of radio coverage, 2 x (4 min + Timer t3512) expires
Result: UE is implicitly de-registered, PDU session is not released
The steps of implicit de-registeration:
1. Implicit Timer Expiration
2. UDM_SDM_Unsubscribe
3. UDM_UECM_Deregistration
4. PDU session release request
5. PDUSessionResourceReleaseCommand + PDU session release command
6. PDUSessionResourceReleaseResponse
7. AM_Policy_Association_Termination
So PDU session release is performed after the confirmation of
UDM_UECM_Deregistration.
Since there is no UDM_SDM subscription, the UDM steps are skipped
and PDU session is not released.
Fix:
If the AMF does not have subscription data for the UE which registers,
the AMF registers with the UDM using Nudm_UECM_Registration and
retrieves subscription data with Nudm_SDM_Get.
[ETSI TS 123 502 V16.7.0](https://www.etsi.org/deliver/etsi_ts/123500_123599/123502/16.07.00_60/ts_123502v160700p.pdf), 4.2.2.2.2 General Registration, 14a-c:
> If the AMF does not have subscription data for the UE, the AMF retrieves the Access and Mobility Subscription data, SMF
> Selection Subscription data, UE context in SMF data and LCS mobile origination using Nudm_SDM_Get.
1. UE sends RegistrationRequest to AMF.
2. AMF sends Nudm_UECM_Registration to UDM.
3. UE sends RegistrationRequest to AMF.
4. GMM state is gmm_state_authentication
5. UDM sends Nudm_UECM_Registration response to AMF.
6. AMF crashs since no Handler in gmm_state_authentication state
According to 3GPP TS 29.510, the search parameter "tai" should be a
single item, not an array of items.
TS 29.510: Table 6.2.3.2.3.1-1:
URI query parameters supported by the GET method on this resource
Revert "[SBI] Change discovery option TAI from array to single item"
This reverts commit b4beff1ae16c64b3c6d84d8bdb47c36e19b705f2.
wip
This commit splits filling Requested-Service-Unit, Used-Service-Unit and
QoS-Information into their own helper functions for better readibility,
and then partially reverts 125740727e,
where lots of AVPs were left out of INITIAL_REQUEST messagesi during the
changes made.
After looking through 3GPP TS 32.299 and rfc4006, it seems expected to
send Requested-Service-Unit only during INITIAL_REQUEST, and
Used-Service-Unit during UPDATE_REQUEST, so that part is kept.
However, I am not able to find clear indications that AVPs such as QoS
Information and RAT-Type should not be sent during INITIAL_REQUEST.
So, since we have the info, better set it already during
INITIAL_REQUEST, since the OCS may want to grant different resources
based on that information if available too.
* [AUSF] Fix removing UE context on authentication removal request
AUSF crashed when trying to access ausf_ue->sm fields after they were
already deleted.
* [AMF] Delete UE authentication result after UE deregisters from 5G core
Based on TS 29.509 - 5.2.2.2.5 Authentication Result Removal with 5G AKA
method:
In the case that the Purge of subscriber data in AMF after the UE
deregisters from the network or the NAS SMC fails following the
successful authentication in the registration procedure, the NF Service
Consumer (AMF) requests the AUSF to inform the UDM to remove the
authentication result.
amf_ue->mac_failed flag to be cleared during security mode procedure but it was not.
At this point, the only way to cleare the amf_ue->mac_failed flag is by UE Context Release.
But I'd like to connect UEs as fast as possible without UE Context Release.
* Add "subscriber_status" cmd to open5gs-dbctl to set values for
"subscriber_status" and "operator_determined_barring" DB fields.
* Add webui View+Edit for those same fields.
* open5gs-hssd now takes those values into account and submits
Operator-Determined-Barring AVP with DB-retrieved value if
subscriber_status is set to OPERATOR_DETERMINED_BARRING.
For more information, see TS 29.272 section 5.2.2.1.3 and 7.3.30.
currently if no IP address is available from the configured
subnets in the SMF when attempting to assign an IP to an UE
we assert and the SMF crashes. Handle the error more gracefully
by returning an error cause instead.
Scenario is handover on S1AP, data forwarding is enabled, and
the Source ENB is forwarding DL PDCP packets to EPC(SGWU)
with PDCP SN included. SGWU is also forwarding these packets
to the Target ENB.
However the PDCP SN is not present in the forwarded packets
from SGWU to Target ENB.
I modified this part, and there was the same problem in 5GC, fixed it as well.
A lot of code in GTP-U has been modified,
so if you have any problems, please let us know right away.
curl --noproxy '*' --http2-prior-knowledge -X POST --header "Content-Type: multipart/related" --data-binary @pdu http:/192.168.29.231:7777/nsmf-pdusession/v1/sm-contexts
Attaching file 'pdu'
SMF crashes as not able to decode the message properly. SmContextCreateData is not accessible.
Modifications were made to resolve the following assertion..
Invalid HNET PKI Value [0] (../lib/sbi/conv.c:135)
ogs_supi_from_supi_or_suci: Expectation `supi' failed. (../lib/sbi/conv.c:262)
udm_ue_add: Assertion `udm_ue->supi' failed. (../src/udm/context.c:144)
backtrace() returned 8 addresses (../lib/core/ogs-abort.c:37)
A situation in which you establish two sessions and release both of them.
In the first SESSION, the UE normally sent PDUSessionResourceReleaseResponse
and PDU session release complete. However, these were not sent when releasing
the second SESSION.
At this point, when the UE tried to do a deregistration,
the SMF was not properly handling the exception.
I've just fixed this.
NAS, GTP, PFCP, SBI, all except S1AP/NGAP use x1000 multiplier for Kbps, Mbps, Gbps ... etc.
From now on in WebUI all units also use a multiplier of x1000.