Commit Graph

1651 Commits

Author SHA1 Message Date
Sukchan Lee 02d302b15a [SEC] Fix Assertion ogs_pfcp_parse_volume (#3207) 2024-05-18 21:37:28 +09:00
Sukchan Lee 15ff23de75 [SEC] Fix Assertion ogs_pfcp_parse_sdf_filter (#3207) 2024-05-18 21:37:28 +09:00
Sukchan Lee bd4d925f0f [SEC] Fix Assertion ogs_pfcp_parse_user_plane_ip_resource_info() (#3207) 2024-05-18 21:37:28 +09:00
Sukchan Lee 5f425445a8 [SEC] Fix Assertion ogs_gtp2_parse_uli (#3209) 2024-05-18 21:37:28 +09:00
Sukchan Lee 05deed616c [SEC] fix Assertion `0 < ogs_fadn_parse` (#3207) 2024-05-18 21:37:28 +09:00
Sukchan Lee 4599b273fa [MME] Problem keep changing PDN-Type (#3209)
If the UE continuously attempts to Attach while changing PDN Type,
it will cause the wrong IP to be assigned.
(e.g PDU-Type : IPv4v6 -> IPv4 -> IPv4v6)

This is because we use two variables at the same time,
one to read and store the Static IP from the Subscriber DB and
one to store the IP assigned from SMF, called session->paa.

When the UE attaches with PDN-Type set to IPv4v6,
MME saves the allocated IP in session->paa.

However, MME thinks it has been assigned a static IP based on the information
in session->paa, so changing the PDN-Type may result in the wrong IP
being assigned.

To solve this problem, I separated the variable(session->paa) that stores
the allocated IP received from SMF and the variable(session->ue_ip) that stores
the Static IP read from the Subscriber DB.

Therefore, the information read from the Subscriber DB
(session->session_type and session->ue_ip) should not be modified.
2024-05-18 14:01:00 +09:00
Sukchan Lee 95de14c72b [SBI] SearchResult.validityPeriod 3600->30s (#3210)
The validity time for NF Instances obtained through NF Discovery was
not properly implemented. Since the validity was 3600 seconds(1 hour),
which caused 5G Core to not work properly after 3600 seconds(1 hour).

There was an issue where an NF Instance should be deleted
when its validity time expired, but it was not working correctly
due to incorrect use of reference count.

Therefore, I have modified the Validity of NF Instances obtained
through NF Discovery to work properly.

I also changed the default value of valdityPeriod to 30 seconds.
2024-05-17 14:54:32 +09:00
Sukchan Lee 7a9fea8aec [SBI] Re-factor NF Instance Context (#3093)
Fixed not using Reference Count for adding/deleting NF Instances.

Up until now, NF Instances have been managed by referencing the Reference Count.

Initially, when an NF Instance is added, the Reference Count is incremented and
when it is deleted, the Reference Count is decremented.

If a UE discovers another NF Instance through the NF Discovery function,
the Reference Count is incremented. And if a UE de-registers,
the Reference Count of the discovered NF is decremented.

However, there's a problem with this approach.

When other NF is de-registered,
there is no guarantee that it will be 100% notified.

For example, if a UDM is de-registered, but an SCP is de-registered before it,
the AMF will not be notified that the UDM has been de-registered.

In situations where this is not clear, Reference Count cannot be used.

Therefore, we have modified it to not use the Reference Count method.

Also, when a UE connects, it is modified to always search
whether an NF Instance exists by NF Instance ID whenever it is discovered.

To do this, we modified lib/sbi/path.c as shown below.

```diff
@@ -281,13 +281,15 @@ int ogs_sbi_discover_and_send(ogs_sbi_xact_t *xact)
     }

     /* Target NF-Instance */
-    nf_instance = sbi_object->service_type_array[service_type].nf_instance;
+    nf_instance = ogs_sbi_nf_instance_find(
+            sbi_object->service_type_array[service_type].nf_instance_id);
     if (!nf_instance) {
         nf_instance = ogs_sbi_nf_instance_find_by_discovery_param(
                         target_nf_type, requester_nf_type, discovery_option);
-        if (nf_instance)
-            OGS_SBI_SETUP_NF_INSTANCE(
-                    sbi_object->service_type_array[service_type], nf_instance);
+        if (nf_instance) {
+            OGS_SBI_SETUP_NF_INSTANCE_ID(
+                    sbi_object->service_type_array[service_type], nf_instance->id);
+        }
     }
```
2024-05-12 10:24:15 +09:00
Sukchan Lee 048a74005b [SEC] Heap overflow in parse PLMN-ID (#3154)
An assert shall be triggered if sepp_node is corrupted.

```
pwndbg> p *sepp_node
$5 = {
  lnode = {
    prev = 0x0,
    next = 0xaaaac920c638
  },
  receiver = 0xaaaac9230990 "sepp2.localdomain",
  negotiated_security_scheme = OpenAPI_security_capability_TLS,
  target_apiroot_supported = true,
  plmn_id = {{
      mcc1 = 6 '\006',
      mcc2 = 6 '\006',
      mcc3 = 6 '\006',
      mnc1 = 6 '\006',
      mnc2 = 6 '\006',
      mnc3 = 6 '\006'
    } <repeats 12 times>},
  num_of_plmn_id = 6710887,
  target_plmn_id_presence = false,
  target_plmn_id = {
    mcc1 = 0 '\000',
    mcc2 = 0 '\000',
    mcc3 = 0 '\000',
    mnc1 = 0 '\000',
    mnc2 = 0 '\000',
    mnc3 = 0 '\000'
  },
  supported_features = 1,
  sm = {
    init = 0xaaaaada181fc <sepp_handshake_state_initial>,
    fini = 0xaaaaada18390 <sepp_handshake_state_final>,
    state = 0xaaaaada194b4 <sepp_handshake_state_established>
  },
  t_establish_interval = 0xffffa7d6c4e0,
  client = 0xaaaac91af010,
  n32f = {
    client = 0xaaaac91af090
  }
}
pwndbg> p/x sepp_node.num_of_plmn_id
$6 = 0x666667
```
2024-04-30 22:10:45 +09:00
Sukchan Lee a9b1b116b3 [SBI] Generate URI via HTTP.location as is (#3058)
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.
2024-04-18 21:24:07 +09:00
Oliver Smith 7973e45d16 [CORE] logger: add option to disable timestamps
Add an option to disable printing the timestamp. This is useful to not
have duplicate timestamps, when stderr is piped into a logging system
that adds timestamps on its own. For example with systemd's journald:

$ journalctl -u open5gs-smfd
Apr 10 13:25:18 hostname open5gs-smfd[1582]: 04/10 13:25:18.274: [app] INFO: Configuration: '/etc/open5gs/smf.yaml' (../lib/app/ogs-init.c:130)

Configuration change:
```
<OLD Format>
logger:
  file: /var/log/open5gs/smf.log

<NEW Format>
logger:
  file:
    path: /var/log/open5gs/smf.log
```

Example config, to have no timestamps on stderr:
```
logger:
  default:
    timestamp: false
  file:
    path: /var/log/open5gs/smf.log
    timestamp: true
```
2024-04-18 21:08:35 +09:00
Sukchan Lee f960047ccb [SMF/UPF] Follow-up on Pull #3137 (Issues #2975) 2024-04-14 09:19:07 +09:00
Sukchan Lee a6830b30a0 [SMF/UPF] Changes subnet configuration (#2975)
The way subnet is set up has changed as shown below.

```
<OLD Format>
smf:
  session:
    - subnet: 10.45.0.1/16

<NEW Format>
smf:
  session:
    - subnet: 10.45.0.0/16
      gateway: 10.45.0.1
```

For more information, please refer to Pull Request #2975.
2024-04-13 19:31:19 +09:00
Sukchan Lee 2b6369e9d9 [SMF] crash when malformed NAS message (#3132)
A malformed PDU Session Modification Request is sent from UE
after Registration Complete.

```
Crash 1:
04/12 15:00:44.031: [amf] INFO: [imsi-999700000000001:1:11][0:0:NULL] /nsmf-pdusession/v1/sm-contexts/{smContextRef}/modify (../src/amf/nsmf-handler.c:837)
04/12 15:00:46.569: [nas] FATAL: ogs_nas_parse_qos_flow_descriptions: Assertion `descriptions->length' failed. (../lib/nas/5gs/types.c:486)
04/12 15:00:46.569: [core] FATAL: backtrace() returned 11 addresses (../lib/core/ogs-abort.c:37)
../src/smf/../../lib/nas/5gs/libogsnas-5gs.so.2(ogs_nas_parse_qos_flow_descriptions+0x162) [0x7e6e7a5a4e5d]
../src/smf/open5gs-smfd(+0x8c6ec) [0x5dd6c333d6ec]
../src/smf/open5gs-smfd(+0x2d69b) [0x5dd6c32de69b]
../src/smf/../../lib/core/libogscore.so.2(ogs_fsm_dispatch+0x119) [0x7e6e7b216c0c]
../src/smf/open5gs-smfd(+0x288b3) [0x5dd6c32d98b3]
../src/smf/../../lib/core/libogscore.so.2(ogs_fsm_dispatch+0x119) [0x7e6e7b216c0c]
../src/smf/open5gs-smfd(+0xf2d8) [0x5dd6c32c02d8]
../src/smf/../../lib/core/libogscore.so.2(+0x1197a) [0x7e6e7b20797a]
/lib/x86_64-linux-gnu/libc.so.6(+0x94ac3) [0x7e6e7a094ac3]
/lib/x86_64-linux-gnu/libc.so.6(+0x126850) [0x7e6e7a126850]
04/12 15:00:46.613: [app] ERROR: Signal-NUM[17] received (Child status change) (../src/main.c:81)
04/12 15:00:46.613: [sbi] WARNING: [92] HTTP/2 stream 19 was not closed cleanly before end of the underlying stream (../lib/sbi/client.c:626)
04/12 15:00:46.613: [scp] WARNING: response_handler() failed [-1] (../src/scp/sbi-path.c:539)
04/12 15:00:46.613: [amf] ERROR: [1:0] No SmContextUpdateError [500] (../src/amf/nsmf-handler.c:866)
04/12 15:00:46.613: [amf] ERROR: AMF_SESS_CLEAR (../src/amf/amf-sm.c:484)
04/12 15:00:46.613: [amf] INFO: [Removed] Number of AMF-Sessions is now 0 (../src/amf/context.c:2551)
04/12 15:00:50.596: [nrf] WARNING: [c466ec64-f8fe-41ee-a888-194dc4363612] No heartbeat (../src/nrf/nrf-sm.c:260)
04/12 15:00:50.596: [nrf] INFO: [c466ec64-f8fe-41ee-a888-194dc4363612] NF de-registered (../src/nrf/nf-sm.c:205)
04/12 15:00:50.596: [sbi] INFO: [c466ec64-f8fe-41ee-a888-194dc4363612:1] NF removed (../lib/sbi/nnrf-handler.c:750)
04/12 15:00:50.596: [sbi] INFO: [c466ec64-f8fe-41ee-a888-194dc4363612:1] NF removed (../lib/sbi/nnrf-handler.c:750)
04/12 15:00:55.094: [pfcp] WARNING: [10] LOCAL  No Reponse. Give up! for step 1 type 1 peer [127.0.0.4]:8805 (../lib/pfcp/xact.c:599)
04/12 15:00:55.094: [upf] WARNING: No Heartbeat from SMF [127.0.0.4]:8805 (../src/upf/pfcp-sm.c:329)
04/12 15:00:55.094: [upf] INFO: PFCP de-associated [127.0.0.4]:8805 (../src/upf/pfcp-sm.c:199)
04/12 15:01:02.599: [pfcp] WARNING: [11] LOCAL  No Reponse. Give up! for step 1 type 5 peer [127.0.0.4]:8805 (../lib/pfcp/xact.c:599)
04/12 15:01:06.098: [upf] WARNING: Retry to association with peer [127.0.0.4]:8805 failed (../src/upf/pfcp-sm.c:107)

Crash 2:
04/12 15:16:39.748: [amf] INFO: [imsi-999700000000001:1:11][0:0:NULL] /nsmf-pdusession/v1/sm-contexts/{smContextRef}/modify (../src/amf/nsmf-handler.c:837)
04/12 15:16:42.155: [nas] FATAL: ogs_nas_parse_qos_rules: Assertion `size+sizeof(rule->flow.flags) <= length' failed. (../lib/nas/5gs/types.c:961)
04/12 15:16:42.155: [core] FATAL: backtrace() returned 11 addresses (../lib/core/ogs-abort.c:37)
../src/smf/../../lib/nas/5gs/libogsnas-5gs.so.2(ogs_nas_parse_qos_rules+0x12d1) [0x7d1affbd2d72]
../src/smf/open5gs-smfd(+0x8b446) [0x629a57861446]
../src/smf/open5gs-smfd(+0x2d69b) [0x629a5780369b]
../src/smf/../../lib/core/libogscore.so.2(ogs_fsm_dispatch+0x119) [0x7d1affd05c0c]
../src/smf/open5gs-smfd(+0x288b3) [0x629a577fe8b3]
../src/smf/../../lib/core/libogscore.so.2(ogs_fsm_dispatch+0x119) [0x7d1affd05c0c]
../src/smf/open5gs-smfd(+0xf2d8) [0x629a577e52d8]
../src/smf/../../lib/core/libogscore.so.2(+0x1197a) [0x7d1affcf697a]
/lib/x86_64-linux-gnu/libc.so.6(+0x94ac3) [0x7d1afea94ac3]
/lib/x86_64-linux-gnu/libc.so.6(+0x126850) [0x7d1afeb26850]
04/12 15:16:42.199: [sbi] WARNING: [92] HTTP/2 stream 13 was not closed cleanly before end of the underlying stream (../lib/sbi/client.c:626)
04/12 15:16:42.199: [scp] WARNING: response_handler() failed [-1] (../src/scp/sbi-path.c:539)
04/12 15:16:42.199: [app] ERROR: Signal-NUM[17] received (Child status change) (../src/main.c:81)
04/12 15:16:42.200: [amf] ERROR: [1:0] No SmContextUpdateError [500] (../src/amf/nsmf-handler.c:866)
04/12 15:16:42.200: [amf] ERROR: AMF_SESS_CLEAR (../src/amf/amf-sm.c:484)
04/12 15:16:42.200: [amf] INFO: [Removed] Number of AMF-Sessions is now 0 (../src/amf/context.c:2551)
04/12 15:16:49.858: [nrf] WARNING: [23f1aee2-f901-41ee-a488-85a58e1e3420] No heartbeat (../src/nrf/nrf-sm.c:260)
04/12 15:16:49.858: [nrf] INFO: [23f1aee2-f901-41ee-a488-85a58e1e3420] NF de-registered (../src/nrf/nf-sm.c:205)
04/12 15:16:49.859: [sbi] INFO: [23f1aee2-f901-41ee-a488-85a58e1e3420:1] NF removed (../lib/sbi/nnrf-handler.c:750)
04/12 15:16:49.859: [sbi] INFO: [23f1aee2-f901-41ee-a488-85a58e1e3420:1] NF removed (../lib/sbi/nnrf-handler.c:750)
04/12 15:16:59.364: [pfcp] WARNING: [5] LOCAL  No Reponse. Give up! for step 1 type 1 peer [127.0.0.4]:8805 (../lib/pfcp/xact.c:599)
04/12 15:16:59.364: [upf] WARNING: No Heartbeat from SMF [127.0.0.4]:8805 (../src/upf/pfcp-sm.c:329)
04/12 15:16:59.364: [upf] INFO: PFCP de-associated [127.0.0.4]:8805 (../src/upf/pfcp-sm.c:199)
```

So, I've fixed it.
2024-04-13 15:03:09 +09:00
Pau Espin cfd4f28f8a cosmetic: Fix trailing whitespace 2024-04-09 07:13:51 +09:00
Pau Espin b30604b289 [SMF] Initial implementation of Final-Unit-Indication
Only "Terminate" action is implemented so far, and it will be used
regardless of the action provided by the OCS.
2024-04-09 07:13:33 +09:00
Sukchan Lee 8484a5af60 [GTP] Incorrect destination TEID=0 (#3043)
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.
2024-04-06 16:39:32 +09:00
gstaa eb2b19b39c
Include cause in HTTP response ProblemDetails (#3051)
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
2024-04-04 23:29:20 +09:00
Pau Espin 3ee4bb7d3c pfcp: Fix missing fields in ogs_pfcp_build_update_urr()
Flag bitmask check elements are reordered to follow same order as
IEs in 3GPP TS 29.244 7.5.4.4 "Update URR".
2024-04-04 23:23:32 +09:00
Sukchan Lee d32cc14a71 [DBI] mongoc version not checked correctly #3086
checks mongoc version with

which can unexpectedly return false in case of mongoc versions such as 2.3.4.

So, I've fixed it as below.
2024-03-31 20:41:50 +09:00
Sukchan Lee e8a3b76af3 [SMF] Crash SMF when no GTP-C config (#3094)
When GTP-C secition of smf.yaml is deleted as follows to run smf as 5G,
it crashed.

```diff
--- smf.yaml.orig       2024-03-26 14:13:12.000000000 +0900
+++ smf.yaml    2024-03-26 14:29:40.701508424 +0900
@@ -23,9 +23,6 @@
     client:
       upf:
         - address: 127.0.0.7
-  gtpc:
-    server:
-      - address: 127.0.0.4
   gtpu:
     server:
       - address: 127.0.0.4
@@ -47,7 +44,7 @@
 #    - ::1
 #  ctf:
 #    enabled: auto   # auto(default)|yes|no
-  freeDiameter: /root/open5gs/install/etc/freeDiameter/smf.conf
+#  freeDiameter: /root/open5gs/install/etc/freeDiameter/smf.conf

 ################################################################################
 # SMF Info
Open5GS daemon v2.7.0-119-g581d255

03/26 14:39:42.844: [app] INFO: Configuration: 'install/etc/open5gs/smf.yaml' (../lib/app/ogs-init.c:130)
03/26 14:39:42.845: [app] INFO: File Logging: '/root/open5gs/install/var/log/open5gs/smf.log' (../lib/app/ogs-init.c:133)
03/26 14:39:42.913: [metrics] INFO: metrics_server() [http://127.0.0.4]:9090 (../lib/metrics/prometheus/context.c:299)
03/26 14:39:42.913: [smf] WARNING: No diameter configuration (../src/smf/fd-path.c:30)
03/26 14:39:42.913: [smf] FATAL: smf_gtp_open: Assertion `ogs_gtp_self()->gtpc_sock || ogs_gtp_self()->gtpc_sock6' failed. (../src/smf/gtp-path.c:253)
03/26 14:39:42.913: [core] FATAL: backtrace() returned 8 addresses (../lib/core/ogs-abort.c:37)
./install/bin/open5gs-smfd(+0x391ab) [0x55d28319b1ab]
./install/bin/open5gs-smfd(+0x10046) [0x55d283172046]
./install/bin/open5gs-smfd(+0xf3de) [0x55d2831713de]
./install/bin/open5gs-smfd(+0xfcf9) [0x55d283171cf9]
/lib/x86_64-linux-gnu/libc.so.6(+0x29d90) [0x7f0a145f9d90]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80) [0x7f0a145f9e40]
./install/bin/open5gs-smfd(+0xf305) [0x55d283171305]
Aborted (core dumped)
```

So, Fixed to run SMF with GTP-C disabled for 5G.
2024-03-31 20:25:25 +09:00
Sukchan Lee 581d255c53 Revert "[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)"
This reverts commit a667525041.
2024-03-26 08:04:26 +09:00
Sukchan Lee 7c14073533 [UDM] Added validation for pubkey
a cryptographic vulnerability in the SUCI decryption routines
of Open5GS 5G—specifically Profile B, which uses P-256 (secp256r1)
for its elliptic curve routines.

If a mobile device user passes a public key within its SUCI
that does not correspond to a valid point on the P-256 elliptic curve,
the Open5GS UDM will not check the point
before running elliptic curve operations with it and returning a response
to the mobile device user.

If the public key is not checked to be a valid point, an attacker can leverage
this behavior to extract the Profile B private key from the UDM,
as has been done in other domains
(https://owasp.org/www-pdf-archive/Practical_Invalid_Curve_Attacks_on_TLS-ECDH_-_Juraj_Somorovsky.pdf).

Note that Profile A is not similarly vulnerable to this, as it is impossible
to construct an invalid point on a curve25519 elliptic curve.

There was some work that went into developing a practical proof of concept
of this kind of attack against free5gc last year; it can be found here:

https://www.gsma.com/security/wp-content/uploads/2023/10/0073-invalid_curve.pdf

And here is the free5gc security advisory:

https://github.com/advisories/GHSA-cqvv-r3g3-26rf

To mitigate this issue in Open5GS, the public key of the UE must be validated
by the UDM prior to use. Adding a validation function such as the following
should work:

I designed this code based on information from https://crypto.stackexchange.com/questions/90151/verify-that-a-point-belongs-to-secp256r1.
2024-03-24 14:09:10 +09:00
Sukchan Lee cf4ad1f248 [PFCP] Session removal while waiting PFCP reply (#3040)
'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.
2024-03-24 09:50:23 +09:00
Sukchan Lee a667525041 [GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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);
2024-03-23 10:06:16 +09:00
Pau Espin 12158eebb8 [SMF] Gy: Check Multiple-Services-Credit-Control Result-Code 2024-03-21 07:13:44 +09:00
Matej Gradišar e1820e4e54
UE context transfer (#3052)
* [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>
2024-03-21 07:07:25 +09:00
Bostjan Meglic f66c65b9cf [SBI] Fix handling "dnn" URL parameter
Split handling discovery and other URL parameters into 2 distinct sets,
to prevent bugs with overlaps.
2024-03-18 17:59:57 +09:00
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
Pau Espin b31fc343d1 cosmetic: Document spec references for unassigned identity values 2024-03-08 21:51:36 +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 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
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
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 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 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 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 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
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
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