CVE-2021-45462: Improper Validation of Specified Quantity in Input (CWE-1284)
value: In Open5GS 2.4.0, a crafted packet from UE can crash SGW-U/UPF.
CWE description: The product receives input that is expected to specify a quantity (such as size or length), but it does not validate or incorrectly validates that the quantity has the required properties.
CVSS v3 base score: 7.5
Published: 2021-12-23T04:15Z
Repository: https://github.com/open5gs/open5gs
Language: C
Files changed: src/sgwu/gtp-path.c, src/smf/gtp-path.c, src/upf/gtp-path.c
Commit date: 2021-12-22 20:55:48 +0900
Commit message: A crafted packet from UE can crash SGW-U/UPF

Diff: diff --git a/src/sgwu/gtp-path.c b/src/sgwu/gtp-path.c
index c523e3e3c..b72f1aa5d 100644
--- a/src/sgwu/gtp-path.c
+++ b/src/sgwu/gtp-path.c
@@ -122,10 +122,16 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
     if (len < 0) {
         ogs_error("[DROP] Cannot decode GTPU packet");
         ogs_log_hexdump(OGS_LOG_ERROR, pkbuf->data, pkbuf->len);
         goto cleanup;
     }
+    if (gtp_h->type != OGS_GTPU_MSGTYPE_END_MARKER &&
+        pkbuf->len <= len) {
+        ogs_error("[DROP] Small GTPU packet(type:%d len:%d)", gtp_h->type, len);
+        ogs_log_hexdump(OGS_LOG_ERROR, pkbuf->data, pkbuf->len);
+        goto cleanup;
+    }
     ogs_assert(ogs_pkbuf_pull(pkbuf, len));
 
     if (gtp_h->type == OGS_GTPU_MSGTYPE_END_MARKER) {
         /* Nothing */
 
diff --git a/src/smf/gtp-path.c b/src/smf/gtp-path.c
index 8e825fe62..821341ce8 100644
--- a/src/smf/gtp-path.c
+++ b/src/smf/gtp-path.c
@@ -184,10 +184,16 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
     if (len < 0) {
         ogs_error("[DROP] Cannot decode GTPU packet");
         ogs_log_hexdump(OGS_LOG_ERROR, pkbuf->data, pkbuf->len);
         goto cleanup;
     }
+    if (gtp_h->type != OGS_GTPU_MSGTYPE_END_MARKER &&
+        pkbuf->len <= len) {
+        ogs_error("[DROP] Small GTPU packet(type:%d len:%d)", gtp_h->type, len);
+        ogs_log_hexdump(OGS_LOG_ERROR, pkbuf->data, pkbuf->len);
+        goto cleanup;
+    }
     ogs_assert(ogs_pkbuf_pull(pkbuf, len));
 
     if (gtp_h->type == OGS_GTPU_MSGTYPE_GPDU) {
         smf_sess_t *sess = NULL;
         ogs_pfcp_far_t *far = NULL;
diff --git a/src/upf/gtp-path.c b/src/upf/gtp-path.c
index b18b7c51b..95bb5b99a 100644
--- a/src/upf/gtp-path.c
+++ b/src/upf/gtp-path.c
@@ -302,10 +302,16 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
     if (len < 0) {
         ogs_error("[DROP] Cannot decode GTPU packet");
         ogs_log_hexdump(OGS_LOG_ERROR, pkbuf->data, pkbuf->len);
         goto cleanup;
     }
+    if (gtp_h->type != OGS_GTPU_MSGTYPE_END_MARKER &&
+        pkbuf->len <= len) {
+        ogs_error("[DROP] Small GTPU packet(type:%d len:%d)", gtp_h->type, len);
+        ogs_log_hexdump(OGS_LOG_ERROR, pkbuf->data, pkbuf->len);
+        goto cleanup;
+    }
     ogs_assert(ogs_pkbuf_pull(pkbuf, len));
 
     if (gtp_h->type == OGS_GTPU_MSGTYPE_END_MARKER) {
         /* Nothing */
 

Fixed code:     if (gtp_h->type != OGS_GTPU_MSGTYPE_END_MARKER &&
        pkbuf->len <= len) {
        ogs_error("[DROP] Small GTPU packet(type:%d len:%d)", gtp_h->type, len);
        ogs_log_hexdump(OGS_LOG_ERROR, pkbuf->data, pkbuf->len);
        goto cleanup;
    }
    if (gtp_h->type != OGS_GTPU_MSGTYPE_END_MARKER &&
        pkbuf->len <= len) {
        ogs_error("[DROP] Small GTPU packet(type:%d len:%d)", gtp_h->type, len);
        ogs_log_hexdump(OGS_LOG_ERROR, pkbuf->data, pkbuf->len);
        goto cleanup;
    }
    if (gtp_h->type != OGS_GTPU_MSGTYPE_END_MARKER &&
        pkbuf->len <= len) {
        ogs_error("[DROP] Small GTPU packet(type:%d len:%d)", gtp_h->type, len);
        ogs_log_hexdump(OGS_LOG_ERROR, pkbuf->data, pkbuf->len);
        goto cleanup;
    }