Commit Graph

4377 Commits

Author SHA1 Message Date
Sukchan Lee 7063d853e7 [SBI] Preamble parsing issues in MIME (#3058)
When building the MIME Multipart Media Encapsulation format
within an SBI message in the NF of a third-party product,
Open5GS does not parse properly if it contains a Preamble CRLF.

For example,

```
    TCP/HTTP2
    Stream: Data, Stream ID: 1, Length 841
    MIME Multipart Media Encapsulation, Type: multipart/related, Boundary: "gc0pJq08jU534c"
--->Preamble: 0d0a
    First boundary: --gc0pJq08jU534c\r\n
    Encapsulated multipart part: (application/json)
    Boundary: \r\n--gc0pJq08jU534c\r\n
    Encapsulated multipart part: (application/vnd.3gpp.5gnas)
    Boundary: \r\n--gc0pJq08jU534c\r\n
    Encapsulated multipart part: (application/vnd.3gpp.ngap)
    Last Boundary: \r\n--gc0pJq08jU534c--\r\n
```
2024-03-17 10:36:29 +09:00
Sukchan Lee a1a0a8c0a6 [MME] Race condition between S1AP and S6A
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.
2024-03-16 23:08:07 +09:00
Pau Espin a1bd80515b [MME] Assign valid PTI to sess created by mobility from 2G
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
2024-03-09 06:03:43 +09:00
Pau Espin b31fc343d1 cosmetic: Document spec references for unassigned identity values 2024-03-08 21:51:36 +09:00
mitmitmitm a2b0284172 [SMF] Don't FSM_TRAN smf-sm into incorrect state 2024-03-08 21:14:07 +09:00
Pau Espin 054323ba8d [mme] cosmetic: Document spec references stating NSAPI=EBI 2024-03-08 06:46:31 +09:00
Sukchan Lee 322719f3e7 [SEC] Vulnerabilities have been resolved (#2945)
Reachable assertion in amf_ue_set_suci

Location: src/amf/context.c:1968

```
void amf_ue_set_suci(amf_ue_t *amf_ue,
        ogs_nas_5gs_mobile_identity_t *mobile_identity)
{
    amf_ue_t *old_amf_ue = NULL;
    amf_sess_t *old_sess = NULL;
    char *suci = NULL;

    ogs_assert(amf_ue);
    ogs_assert(mobile_identity);

    suci = ogs_nas_5gs_suci_from_mobile_identity(mobile_identity);
    ogs_assert(suci);
```

Exploitable by: Base Station
Severity: denial of service
2024-03-06 07:20:50 +09:00
Sukchan Lee 199f4c7add [AMF] Fixed crash in no context setup (#2999)
Remove ogs_assert((__sESS)->gsm_message.n1buf) from AMF_SESS_STORE_5GSM_MESSAGE
because N1 buffer can become NULL during PDU session release.
2024-03-04 21:03:07 +09:00
Sukchan Lee 152b4400f8 Fixed docs for changing WebUI port 3000 => 9999 2024-03-02 16:57:45 +09:00
Sukchan Lee 2ceca49161 [MME/AMF] Fixed crash following Handover Request (#3014)
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 ...
2024-02-29 23:02:38 +09:00
Matej Gradisar 24b9150c15 [SMF] Check config file for overlapping UE subnets for subnets with no DNN 2024-02-28 12:06:02 +00:00
Sukchan Lee 4d7f2fb661 [SMF] Memory leak in Handling APCO IE (#3010) 2024-02-28 20:51:20 +09:00
Pau Espin 32de75b1a5 [SMF] Setup Gy session when creating UE session over S2b interface
So far the Gy session creation triggered by S2b interface (ePDG) was not
implemented. Fix it.
2024-02-28 11:42:33 +00:00
Pau Espin 4aaac999f7 [SMF] Handle APCO IE in S2b GTPv2C CreateSessionRequest/Response
This IE is used by UEs registering through S2b interface (ePDG) to
obtain DNS and P-CSCF server address information.
2024-02-28 11:40:31 +00:00
Sukchan Lee 0dd2ad6557 [MME] Added log messages to find memory problem 2024-02-27 21:16:50 +09:00
Sukchan Lee 9a515e9b1d [GTP-U] Fixed a stack overflow bug (#3003) 2024-02-23 19:59:04 +00:00
Sukchan Lee 41d8934677 [SMF] Added Bi-Directional Flow (#2909)
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>
2024-02-17 20:43:15 +01:00
Sukchan Lee 843c4950ac [ASN1C] Fixed asn1c library on 32bit (#2934)
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/176
https://github.com/mouse07410/asn1c/pull/177
2024-02-12 14:00:06 +09:00
Sukchan Lee 94bd68aa7b [MME] Follow-up on #2916
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.
2024-02-08 18:46:45 +09:00
Sukchan Lee 290df460ef Added UPF performance test with NextEPC 2024-02-05 06:29:36 +09:00
Sukchan Lee 82398811db [UPF] Report after Session was Deleted (#2936)
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.
2024-02-04 09:32:33 +09:00
Sukchan Lee 8762425fbc [AMF] Fixed sm_context_ref failed (#2603, #2917) 2024-02-03 16:59:47 +09:00
Sukchan Lee 7e8f145973 Rollback Pull Request (#1911)
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().
2024-02-03 16:18:26 +09:00
Sukchan Lee d1d3ec6fcb [SEC] Several vulnerabilities have been resolved.
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).
2024-02-03 10:41:12 +09:00
Sukchan Lee be12610fb6 [AMF/MME] No STATE Change for the EMM/GMM-STATUS 2024-02-03 10:16:16 +09:00
Sukchan Lee 47419be650 [AMF/SMF] Resolved the Issue of Session Release Based on the Order of N1/N2 Messages (#2917)
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.
2024-02-03 09:42:09 +09:00
Sukchan Lee 3f0979dab2 [MME] Fixes crash in building s1ap message
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;
          }
          ...
      }
  }
2024-02-02 21:17:41 +09:00
Sukchan Lee 93110d011e [GTP-U] Fixed ogs_pfcp_find_gtpu_resource()(#2923)
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.
2024-01-30 22:39:34 +09:00
Pau Espin 88a77f7bc5 [SMF,MME] Gn: Set Maximum SDU Size QoS field to 1500
Before this patch, it was set as 0, which is Reserved in Network to MS
direction.
2024-01-27 07:11:44 +09:00
Pau Espin a613be8c4c [SMF,MME] Gn: Set Delivery of erroneous SDUs QoS field to No
Before this patch, it was set as 0, which is Reserved in Network to MS
direction.
2024-01-27 07:11:44 +09:00
Pau Espin d95c82b21c [SMF,MME] Gn: Set Delivery order QoS field to No
Before this patch, it was set as 0, which is Reserved in Network to MS
direction.
2024-01-27 07:11:44 +09:00
Pau Espin a5feccf4c8 [SMF] Fix fixed-0 IPCP identifier in PCO ack 2024-01-27 07:10:55 +09:00
Sukchan Lee 3886891833 [MME] Crash due to a race condition
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.
2024-01-25 23:27:34 +09:00
Pau Espin 609c234f0b Document Gy interface spec reference 2024-01-25 07:05:33 +09:00
Pau Espin 64598fab2e Document Gx interface spec references 2024-01-25 07:05:33 +09:00
Pau Espin 29ea85ca4c cosmetic: pcrf/pcrf-gx-path.c: Fix trailing whitespace 2024-01-25 07:05:33 +09:00
Bostjan Meglic dcdfc970ce initialize variables before using them 2024-01-22 17:34:59 +09:00
Bostjan Meglic a3afc4764c memset input/output structure inside the function
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.
2024-01-22 17:34:59 +09:00
Bostjan Meglic e650b66305 fix mismatch of parameters between prototype and declaration 2024-01-22 17:34:59 +09:00
jmasterfunk84 2583fd3c08 Introduce ability for multiple SDM_Subscriptions 2024-01-21 13:16:21 +09:00
Sukchan Lee b94173ab41 [AMF/MME] Fixed M-TMSI pool release (#2307)
M-TMSI pool release was incorrectly modified and has now been corrected.
2024-01-21 11:58:43 +09:00
Gaber Stare d7b896affb [SMF] Build URR at bearer modification 2024-01-20 08:20:24 +09:00
Sukchan Lee 97e1b1bd30 [PFCP] Fixed incorrect TLV names (#2887)
Fixed standards documentation that described incorrect TLV names.
2024-01-19 23:40:20 +09:00
Pau Espin 60691b02d2 [MME] Gn: Introduce initial support for 2G->4G cell reselection
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
2024-01-17 23:05:19 +09:00
Sukchan Lee 4088cdf17d [MME] Hangs on an invalid S1AP message
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.
2024-01-17 20:17:55 +09:00
Pau Espin 52be56b839 [MME] Match any SGSN in same RAI if none with specific RAI+CI found
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.
2024-01-16 06:37:29 +09:00
Pau Espin 078bfc90da [GTPv1] Introduce APIs to decode MM Context and PDP Context IEs
They will be used in a follow-up patch implementing GERAN->EUTRAN idle
mobility.
2024-01-16 06:37:10 +09:00
Pau Espin feaa86fc9c [GTPv1] Fix encoding of MM Context IE if NRSNRA bit not set
The len byte, describing the length of the field coming after it,
is always expected according to the struct definition.
2024-01-16 06:37:10 +09:00
Pau Espin afa2c2c9e0 [CRYPT] Add ogs_kdf_kasme_idle_mobility()
This function is needed by a follow-up patch implementing initial
support for GERAN->EUTRAN idle mobility.
2024-01-16 06:36:44 +09:00
Sukchan Lee b0cf9fcbe7 [AMF] Issue during Concurrent UE Registration (#2839)
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)
2024-01-13 23:16:50 +09:00