CVE-2024-40130: Insufficient Information (NVD-CWE-noinfo)
value: open5gs v2.6.4 is vulnerable to Buffer Overflow. via /lib/core/abts.c.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-07-16T19:15Z
Repository: https://github.com/open5gs/open5gs
Language: C
Files changed: src/main.c, tests/app/5gc-init.c, tests/app/app-init.c, tests/app/epc-init.c, tests/common/application.c, tests/common/context.c, tests/common/context.h, tests/common/gtpu.c, tests/common/ngap-build.c, tests/common/s1ap-handler.c, tests/core/abts-main.c, tests/crypt/abts-main.c, tests/handover/epc-s1-test.c, tests/sctp/abts-main.c, tests/unit/abts-main.c
Commit date: 2023-09-05 21:58:05 +0900
Commit message: Fixed dynamic-stack-buffer-overflow (#2578, #2577)

Diff: diff --git a/src/main.c b/src/main.c
index 329d5b1087..0f993a6a67 100644
--- a/src/main.c
+++ b/src/main.c
@@ -109,11 +109,11 @@ int main(int argc, const char *const argv[])
         char *domain_mask;
 
         bool enable_debug;
         bool enable_trace;
     } optarg;
-    const char *argv_out[argc];
+    const char *argv_out[argc+1];
 
     memset(&optarg, 0, sizeof(optarg));
 
     ogs_getopt_init(&options, (char**)argv);
     while ((opt = ogs_getopt(&options, "vhDc:l:e:m:dt")) != -1) {
diff --git a/tests/app/5gc-init.c b/tests/app/5gc-init.c
index 9589115d12..dfdcac093a 100644
--- a/tests/app/5gc-init.c
+++ b/tests/app/5gc-init.c
@@ -35,11 +35,11 @@ int app_initialize(const char *const argv[])
 {
     const char *argv_out[OGS_ARG_MAX];
     bool user_config = false;
     int i = 0;
 
-    for (i = 0; argv[i]; i++) {
+    for (i = 0; argv[i] && i < OGS_ARG_MAX-3; i++) {
         if (strcmp("-c", argv[i]) == 0) {
             user_config = true; 
         }
         argv_out[i] = argv[i];
     }
diff --git a/tests/app/app-init.c b/tests/app/app-init.c
index 040448d53f..d53601ec4b 100644
--- a/tests/app/app-init.c
+++ b/tests/app/app-init.c
@@ -40,11 +40,11 @@ int app_initialize(const char *const argv[])
 {
     const char *argv_out[OGS_ARG_MAX];
     bool user_config = false;
     int i = 0;
 
-    for (i = 0; argv[i]; i++) {
+    for (i = 0; argv[i] && i < OGS_ARG_MAX-3; i++) {
         if (strcmp("-c", argv[i]) == 0) {
             user_config = true;
         }
         argv_out[i] = argv[i];
     }
diff --git a/tests/app/epc-init.c b/tests/app/epc-init.c
index c84f0ffe2a..7d27ad5941 100644
--- a/tests/app/epc-init.c
+++ b/tests/app/epc-init.c
@@ -31,11 +31,11 @@ int app_initialize(const char *const argv[])
 {
     const char *argv_out[OGS_ARG_MAX];
     bool user_config = false;
     int i = 0;
 
-    for (i = 0; argv[i]; i++) {
+    for (i = 0; argv[i] && i < OGS_ARG_MAX-3; i++) {
         if (strcmp("-c", argv[i]) == 0) {
             user_config = true; 
         }
         argv_out[i] = argv[i];
     }
diff --git a/tests/common/application.c b/tests/common/application.c
index 1bf1a0528b..f934fe5145 100644
--- a/tests/common/application.c
+++ b/tests/common/application.c
@@ -25,11 +25,11 @@ static void run(int argc, const char *const argv[],
 {
     int rv;
     bool user_config;
 
     /* '-f sample-XXXX.conf -e error' is always added */
-    const char *argv_out[argc+4], *new_argv[argc+4];
+    const char *argv_out[argc+5], *new_argv[argc+5];
     int argc_out;
 
     char conf_file[OGS_MAX_FILEPATH_LEN];
     
     user_config = false;
diff --git a/tests/common/context.c b/tests/common/context.c
index c1cf82cbf3..1f1bfa5c5e 100644
--- a/tests/common/context.c
+++ b/tests/common/context.c
@@ -125,11 +125,12 @@ static int test_context_validation(void)
                 OGS_PLMN_ID_LEN);
     }
 
     if (test_self()->nr_served_tai[index].list2.num) {
         memcpy(&test_self()->nr_tai,
-            &test_self()->nr_served_tai[index].list2.tai[0], sizeof(ogs_5gs_tai_t));
+            &test_self()->nr_served_tai[index].list2.tai[0],
+            sizeof(ogs_5gs_tai_t));
     } else if (test_self()->nr_served_tai[index].list1.tai[0].num) {
         test_self()->nr_tai.tac =
             test_self()->nr_served_tai[index].list1.tai[0].tac;
         memcpy(&test_self()->nr_tai.plmn_id,
                 &test_self()->nr_served_tai[index].list1.tai[0].plmn_id,
diff --git a/tests/common/context.h b/tests/common/context.h
index 422a6b2ab1..c54eff9fee 100644
--- a/tests/common/context.h
+++ b/tests/common/context.h
@@ -475,10 +475,17 @@ typedef struct test_bearer_s {
     uint8_t         qfi;            /* 5GC */
     uint8_t         ebi;            /* EPC */
 
     uint32_t        sgw_s1u_teid;   /* SGW-S1U TEID */
     ogs_ip_t        sgw_s1u_ip;     /* SGW-S1U IPv4/IPv6 */
+    struct {
+        /* Indirect Forwarding */
+        uint32_t dl_teid;
+        ogs_ip_t dl_ip;
+        uint32_t ul_teid;
+        ogs_ip_t ul_ip;
+    } handover;
 
     uint32_t        enb_s1u_teid;   /* eNB-S1U TEID */
     ogs_sockaddr_t  *enb_s1u_addr;  /* eNB-S1U IPv4 */
     ogs_sockaddr_t  *enb_s1u_addr6; /* eNB-S1U IPv6 */
 
diff --git a/tests/common/gtpu.c b/tests/common/gtpu.c
index a5c7ce2d36..091e216db3 100644
--- a/tests/common/gtpu.c
+++ b/tests/common/gtpu.c
@@ -533,13 +533,11 @@ int test_gtpu_send_indirect_data_forwarding(
     if (bearer->qfi) {
         gtp_hdesc.teid = sess->handover.upf_dl_teid;
         ext_hdesc.qos_flow_identifier = bearer->qfi;
 
     } else if (bearer->ebi) {
-
-        ogs_fatal("Not implmented EPC Indirect Tunnel");
-        ogs_assert_if_reached();
+        gtp_hdesc.teid = bearer->handover.ul_teid;
 
     } else {
         ogs_fatal("No QFI[%d] and EBI[%d]", bearer->qfi, bearer->ebi);
         ogs_assert_if_reached();
     }
diff --git a/tests/common/ngap-build.c b/tests/common/ngap-build.c
index 1f2a654364..84432701f1 100644
--- a/tests/common/ngap-build.c
+++ b/tests/common/ngap-build.c
@@ -35,11 +35,11 @@ static ogs_pkbuf_t *testngap_build_handover_request_ack_transfer(
         test_sess_t *sess);
 
 ogs_pkbuf_t *testngap_build_ng_setup_request(uint32_t gnb_id, uint8_t bitsize)
 {
     ogs_pkbuf_t *pkbuf = NULL;
-    int i, j;
+    int i, j, k, num = 0;
     ogs_plmn_id_t *plmn_id = NULL;
     const char *ran_node_name = "5G gNB-CU";
 
     NGAP_NGAP_PDU_t pdu;
     NGAP_InitiatingMessage_t *initiatingMessage = NULL;
@@ -116,61 +116,71 @@ ogs_pkbuf_t *testngap_build_ng_setup_request(uint32_t gnb_id, uint8_t bitsize)
     GlobalRANNodeID->choice.globalGNB_ID = globalGNB_ID;
 
     ogs_asn_buffer_to_OCTET_STRING((char*)ran_node_name,
             strlen(ran_node_name), RANNodeName);
 
-    SupportedTAItem = CALLOC(1, sizeof(NGAP_SupportedTAItem_t));
     if (test_self()->nr_served_tai[0].list2.num)
-        ogs_asn_uint24_to_OCTET_STRING(
-            test_self()->nr_served_tai[0].list2.tai[0].tac,
-            &SupportedTAItem->tAC);
+        num = test_self()->nr_served_tai[0].list2.num;
     else if (test_self()->nr_served_tai[0].list0.tai[0].num)
-        ogs_asn_uint24_to_OCTET_STRING(
-            test_self()->nr_served_tai[0].list0.tai[0].tac[0],
-                &SupportedTAItem->tAC);
+        num = test_self()->nr_served_tai[0].list0.tai[0].num;
     else
         ogs_assert_if_reached();
 
-    for (i = 0; i < test_self()->num_of_plmn_support; i++) {
-        plmn_id = &test_self()->plmn_support[i].plmn_id;
+    for (i = 0; i < num; i++) {
+        SupportedTAItem = CALLOC(1, sizeof(NGAP_SupportedTAItem_t));
+        if (test_self()->nr_served_tai[0].list2.num)
+            ogs_asn_uint24_to_OCTET_STRING(
+                test_self()->nr_served_tai[0].list2.tai[i].tac,
+                &SupportedTAItem->tAC);
+        else if (test_self()->nr_served_tai[0].list0.tai[0].num)
+            ogs_asn_uint24_to_OCTET_STRING(
+                test_self()->nr_served_tai[0].list0.tai[0].tac[i],
+                    &SupportedTAItem->tAC);
+        else
+            ogs_assert_if_reached();
 
-        BroadcastPLMNItem = CALLOC(1, sizeof(NGAP_BroadcastPLMNItem_t));
+        for (j = 0; j < test_self()->num_of_plmn_support; j++) {
+            plmn_id = &test_self()->plmn_support[j].plmn_id;
 
-        ogs_asn_buffer_to_OCTET_STRING(
-                plmn_id, OGS_PLMN_ID_LEN, &BroadcastPLMNItem->pLMNIdentity);
+            BroadcastPLMNItem = CALLOC(1, sizeof(NGAP_BroadcastPLMNItem_t));
 
-        for (j = 0; j < test_self()->plmn_support[i].num_of_s_nssai; j++) {
-            ogs_s_nssai_t *s_nssai = &test_self()->plmn_support[i].s_nssai[j];
+            ogs_asn_buffer_to_OCTET_STRING(
+                    plmn_id, OGS_PLMN_ID_LEN, &BroadcastPLMNItem->pLMNIdentity);
 
-            SliceSupportItem = CALLOC(1, sizeof(NGAP_SliceSupportItem_t));
-            ogs_asn_uint8_to_OCTET_STRING(s_nssai->sst,
-                    &SliceSupportItem->s_NSSAI.sST);
-            if (s_nssai->sd.v != OGS_S_NSSAI_NO_SD_VALUE) {
-                SliceSupportItem->s_NSSAI.sD = CALLOC(1, sizeof(NGAP_SD_t));
-                ogs_asn_uint24_to_OCTET_STRING(
-                        s_nssai->sd, SliceSupportItem->s_NSSAI.sD);
+            for (k = 0; k < test_self()->plmn_support[j].num_of_s_nssai; k++) {
+                ogs_s_nssai_t *s_nssai =
+                    &test_self()->plmn_support[j].s_nssai[k];
+
+                SliceSupportItem = CALLOC(1, sizeof(NGAP_SliceSupportItem_t));
+                ogs_asn_uint8_to_OCTET_STRING(s_nssai->sst,
+                        &SliceSupportItem->s_NSSAI.sST);
+                if (s_nssai->sd.v != OGS_S_NSSAI_NO_SD_VALUE) {
+                    SliceSupportItem->s_NSSAI.sD = CALLOC(1, sizeof(NGAP_SD_t));
+                    ogs_asn_uint24_to_OCTET_STRING(
+                            s_nssai->sd, SliceSupportItem->s_NSSAI.sD);
+                }
+
+                ASN_SEQUENCE_ADD(&BroadcastPLMNItem->tAISliceSupportList.list,
+                                SliceSupportItem);
             }
 
-            ASN_SEQUENCE_ADD(&BroadcastPLMNItem->tAISliceSupportList.list,
-                            SliceSupportItem);
+            ASN_SEQUENCE_ADD(&SupportedTAItem->broadcastPLMNList.list,
+                    BroadcastPLMNItem);
         }
 
-        ASN_SEQUENCE_ADD(&SupportedTAItem->broadcastPLMNList.list,
-                BroadcastPLMNItem);
+        ASN_SEQUENCE_ADD(&SupportedTAList->list, SupportedTAItem);
     }
 
-    ASN_SEQUENCE_ADD(&SupportedTAList->list, SupportedTAItem);
-
     *PagingDRX = NGAP_PagingDRX_v32;
 
     return ogs_ngap_encode(&pdu);
 }
 
 ogs_pkbuf_t *testngap_build_ran_configuration_update(bool supported_ta_list)
 {
     ogs_pkbuf_t *pkbuf = NULL;
-    int i, j;
+    int i, j, k, num;
     ogs_plmn_id_t *plmn_id = NULL;
 
     NGAP_NGAP_PDU_t pdu;
     NGAP_InitiatingMessage_t *initiatingMessage = NULL;
     NGAP_RANConfigurationUpdate_t *RANConfigurationUpdate = NULL;
@@ -208,52 +218,66 @@ ogs_pkbuf_t *testngap_build_ran_configuration_update(bool supported_ta_list)
         ie->value.present =
             NGAP_RANConfigurationUpdateIEs__value_PR_SupportedTAList;
 
         SupportedTAList = &ie->value.choice.SupportedTAList;
 
-        SupportedTAItem = CALLOC(1, sizeof(NGAP_SupportedTAItem_t));
         if (test_self()->nr_served_tai[0].list2.num)
-            ogs_asn_uint24_to_OCTET_STRING(
-                test_self()->nr_served_tai[0].list2.tai[0].tac,
-                &SupportedTAItem->tAC);
+            num = test_self()->nr_served_tai[0].list2.num;
         else if (test_self()->nr_served_tai[0].list0.tai[0].num)
-            ogs_asn_uint24_to_OCTET_STRING(
-                test_self()->nr_served_tai[0].list0.tai[0].tac[0],
-                    &SupportedTAItem->tAC);
+            num = test_self()->nr_served_tai[0].list0.tai[0].num;
         else
             ogs_assert_if_reached();
 
-        for (i = 0; i < test_self()->num_of_plmn_support; i++) {
-            plmn_id = &test_self()->plmn_support[i].plmn_id;
-
-            BroadcastPLMNItem = CALLOC(1, sizeof(NGAP_BroadcastPLMNItem_t));
-
-            ogs_asn_buffer_to_OCTET_STRING(
-                    plmn_id, OGS_PLMN_ID_LEN, &BroadcastPLMNItem->pLMNIdentity);
-
-            for (j = 0; j < test_self()->plmn_support[i].num_of_s_nssai; j++) {
-                ogs_s_nssai_t *s_nssai =
-                    &test_self()->plmn_support[i].s_nssai[j];
-
-                SliceSupportItem = CALLOC(1, sizeof(NGAP_SliceSupportItem_t));
-                ogs_asn_uint8_to_OCTET_STRING(s_nssai->sst,
-                        &SliceSupportItem->s_NSSAI.sST);
-                if (s_nssai->sd.v != OGS_S_NSSAI_NO_SD_VALUE) {
-                    SliceSupportItem->s_NSSAI.sD = CALLOC(1, sizeof(NGAP_SD_t));
-                    ogs_asn_uint24_to_OCTET_STRING(
-                            s_nssai->sd, SliceSupportItem->s_NSSAI.sD);
+        for (i = 0; i < num; i++) {
+            SupportedTAItem = CALLOC(1, sizeof(NGAP_SupportedTAItem_t));
+            if (test_self()->nr_served_tai[0].list2.num)
+                ogs_asn_uint24_to_OCTET_STRING(
+                    test_self()->nr_served_tai[0].list2.tai[i].tac,
+                    &SupportedTAItem->tAC);
+            else if (test_self()->nr_served_tai[0].list0.tai[0].num)
+                ogs_asn_uint24_to_OCTET_STRING(
+                    test_self()->nr_served_tai[0].list0.tai[0].tac[i],
+                        &SupportedTAItem->tAC);
+            else
+                ogs_assert_if_reached();
+
+            for (j = 0; j < test_self()->num_of_plmn_support; j++) {
+                plmn_id = &test_self()->plmn_support[j].plmn_id;
+
+                BroadcastPLMNItem = CALLOC(1, sizeof(NGAP_BroadcastPLMNItem_t));
+
+                ogs_asn_buffer_to_OCTET_STRING(
+                        plmn_id, OGS_PLMN_ID_LEN,
+                        &BroadcastPLMNItem->pLMNIdentity);
+
+                for (k = 0; k < test_self()->plmn_support[j].num_of_s_nssai;
+                        k++) {
+                    ogs_s_nssai_t *s_nssai =
+                        &test_self()->plmn_support[j].s_nssai[k];
+
+                    SliceSupportItem = CALLOC(1,
+                            sizeof(NGAP_SliceSupportItem_t));
+                    ogs_asn_uint8_to_OCTET_STRING(s_nssai->sst,
+                            &SliceSupportItem->s_NSSAI.sST);
+                    if (s_nssai->sd.v != OGS_S_NSSAI_NO_SD_VALUE) {
+                        SliceSupportItem->s_NSSAI.sD = CALLOC(
+                                1, sizeof(NGAP_SD_t));
+                        ogs_asn_uint24_to_OCTET_STRING(
+                                s_nssai->sd, SliceSupportItem->s_NSSAI.sD);
+                    }
+
+                    ASN_SEQUENCE_ADD(
+                            &BroadcastPLMNItem->tAISliceSupportList.list,
+                            SliceSupportItem);
                 }
 
-                ASN_SEQUENCE_ADD(&BroadcastPLMNItem->tAISliceSupportList.list,
-                                SliceSupportItem);
+                ASN_SEQUENCE_ADD(&SupportedTAItem->broadcastPLMNList.list,
+                        BroadcastPLMNItem);
             }
 
-            ASN_SEQUENCE_ADD(&SupportedTAItem->broadcastPLMNList.list,
-                    BroadcastPLMNItem);
+            ASN_SEQUENCE_ADD(&SupportedTAList->list, SupportedTAItem);
         }
-
-        ASN_SEQUENCE_ADD(&SupportedTAList->list, SupportedTAItem);
     }
 
     return ogs_ngap_encode(&pdu);
 }
 
diff --git a/tests/common/s1ap-handler.c b/tests/common/s1ap-handler.c
index 5281794eb4..91f5e601b2 100644
--- a/tests/common/s1ap-handler.c
+++ b/tests/common/s1ap-handler.c
@@ -477,18 +477,21 @@ void tests1ap_handle_handover_command(
 {
     int i;
     char buf[OGS_ADDRSTRLEN];
 
     test_sess_t *sess = NULL;
+    test_bearer_t *bearer = NULL;
 
     S1AP_S1AP_PDU_t pdu;
     S1AP_SuccessfulOutcome_t *successfulOutcome = NULL;
     S1AP_HandoverCommand_t *HandoverCommand = NULL;
 
     S1AP_HandoverCommandIEs_t *ie = NULL;
     S1AP_MME_UE_S1AP_ID_t *MME_UE_S1AP_ID = NULL;
     S1AP_ENB_UE_S1AP_ID_t *ENB_UE_S1AP_ID = NULL;
+    S1AP_E_RABSubjecttoDataForwardingList_t
+        *E_RABSubjecttoDataForwardingList = NULL;
 
     ogs_assert(test_ue);
     ogs_assert(message);
 
     successfulOutcome = message->choice.successfulOutcome;
@@ -503,19 +506,61 @@ void tests1ap_handle_handover_command(
             MME_UE_S1AP_ID = &ie->value.choice.MME_UE_S1AP_ID;
             break;
         case S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID:
             ENB_UE_S1AP_ID = &ie->value.choice.ENB_UE_S1AP_ID;
             break;
+        case S1AP_ProtocolIE_ID_id_E_RABSubjecttoDataForwardingList:
+            E_RABSubjecttoDataForwardingList =
+                &ie->value.choice.E_RABSubjecttoDataForwardingList;
+            break;
         default:
             break;
         }
     }
 
     if (MME_UE_S1AP_ID)
         test_ue->mme_ue_s1ap_id = *MME_UE_S1AP_ID;
     if (ENB_UE_S1AP_ID)
         test_ue->enb_ue_s1ap_id = *ENB_UE_S1AP_ID;
+
+    if (E_RABSubjecttoDataForwardingList) {
+        for (i = 0; i < E_RABSubjecttoDataForwardingList->list.count; i++) {
+            S1AP_E_RABDataForwardingItemIEs_t *ie = NULL;
+            S1AP_E_RABDataForwardingItem_t *e_rab = NULL;
+
+            ie = (S1AP_E_RABDataForwardingItemIEs_t *)
+                    E_RABSubjecttoDataForwardingList->list.array[i];
+            ogs_assert(ie);
+            e_rab = &ie->value.choice.E_RABDataForwardingItem;
+
+            bearer = test_bearer_find_by_ue_ebi(test_ue, e_rab->e_RAB_ID);
+            ogs_assert(bearer);
+
+            if (e_rab->dL_gTP_TEID) {
+                memcpy(&bearer->handover.dl_teid, e_rab->dL_gTP_TEID->buf,
+                        sizeof(bearer->handover.dl_teid));
+                bearer->handover.dl_teid = be32toh(bearer->handover.dl_teid);
+            }
+            if (e_rab->dL_transportLayerAddress) {
+                ogs_assert(OGS_OK ==
+                        ogs_asn_BIT_STRING_to_ip(
+                            e_rab->dL_transportLayerAddress,
+                            &bearer->handover.dl_ip));
+            }
+            if (e_rab->uL_GTP_TEID) {
+                memcpy(&bearer->handover.ul_teid, e_rab->uL_GTP_TEID->buf,
+                        sizeof(bearer->handover.ul_teid));
+                bearer->handover.ul_teid = be32toh(bearer->handover.ul_teid);
+            }
+            if (e_rab->uL_TransportLayerAddress) {
+                ogs_assert(OGS_OK ==
+                        ogs_asn_BIT_STRING_to_ip(
+                            e_rab->uL_TransportLayerAddress,
+                            &bearer->handover.ul_ip));
+            }
+        }
+    }
 }
 
 void tests1ap_handle_handover_preparation_failure(
         test_ue_t *test_ue, ogs_s1ap_message_t *message)
 {
diff --git a/tests/core/abts-main.c b/tests/core/abts-main.c
index aa6c187c7f..49e2139194 100644
--- a/tests/core/abts-main.c
+++ b/tests/core/abts-main.c
@@ -75,11 +75,11 @@ int main(int argc, const char *const argv[])
     ogs_getopt_t options;
     struct {
         char *log_level;
         char *domain_mask;
     } optarg;
-    const char *argv_out[argc+2]; /* '-e error' is always added */
+    const char *argv_out[argc+3]; /* '-e error' is always added */
     
     abts_suite *suite = NULL;
     ogs_pkbuf_config_t config;
 
     rv = abts_main(argc, argv, argv_out);
diff --git a/tests/crypt/abts-main.c b/tests/crypt/abts-main.c
index ae4a0e8b99..852786ca47 100644
--- a/tests/crypt/abts-main.c
+++ b/tests/crypt/abts-main.c
@@ -48,11 +48,11 @@ int main(int argc, const char *const argv[])
     ogs_getopt_t options;
     struct {
         char *log_level;
         char *domain_mask;
     } optarg;
-    const char *argv_out[argc+2]; /* '-e error' is always added */
+    const char *argv_out[argc+3]; /* '-e error' is always added */
     
     abts_suite *suite = NULL;
     ogs_pkbuf_config_t config;
 
     rv = abts_main(argc, argv, argv_out);
diff --git a/tests/handover/epc-s1-test.c b/tests/handover/epc-s1-test.c
index 13b226896d..becee46ec9 100644
--- a/tests/handover/epc-s1-test.c
+++ b/tests/handover/epc-s1-test.c
@@ -26,10 +26,11 @@ static void test1_func(abts_case *tc, void *data)
     ogs_socknode_t *gtpu1, *gtpu2;
     ogs_pkbuf_t *emmbuf;
     ogs_pkbuf_t *esmbuf;
     ogs_pkbuf_t *sendbuf;
     ogs_pkbuf_t *recvbuf;
+    ogs_pkbuf_t *pkbuf;
     ogs_s1ap_message_t message;
 
     ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci;
     test_ue_t *test_ue = NULL;
     test_sess_t *sess = NULL;
@@ -327,10 +328,39 @@ static void test1_func(abts_case *tc, void *data)
     /* Receive Handover Command */
     recvbuf = testenb_s1ap_read(s1ap1);
     ABTS_PTR_NOTNULL(tc, recvbuf);
     tests1ap_recv(test_ue, recvbuf);
 
+    /* Send GTP-U ICMP Packet */
+    bearer = test_bearer_find_by_ue_ebi(test_ue, 5);
+    ogs_assert(bearer);
+    rv = test_gtpu_send_ping(gtpu1, bearer, TEST_PING_IPV4);
+    ABTS_INT_EQUAL(tc, OGS_OK, rv);
+
+    /* Receive GTP-U ICMP Packet */
+    recvbuf = test_gtpu_read(gtpu1);
+    ABTS_PTR_NOTNULL(tc, recvbuf);
+
+    /* Copy ICMP Packet */
+    pkbuf = ogs_pkbuf_alloc(NULL, 200);
+    ogs_assert(pkbuf);
+    ogs_pkbuf_reserve(pkbuf, OGS_GTPV1U_5GC_HEADER_LEN);
+    ogs_pkbuf_put(pkbuf, 200-OGS_GTPV1U_5GC_HEADER_LEN);
+    memset(pkbuf->data, 0, pkbuf->len);
+    memcpy(pkbuf->data, recvbuf->data + 8, recvbuf->len - 8);
+
+    ogs_pkbuf_free(recvbuf);
+
+    /* Send GTP-U Packet with Indirect Data Forwarding */
+    rv = test_gtpu_send_indirect_data_forwarding(gtpu1, bearer, pkbuf);
+    ABTS_INT_EQUAL(tc, OGS_OK, rv);
+
+    /* Receive GTP-U ICMP Packet */
+    recvbuf = testgnb_gtpu_read(gtpu2);
+    ABTS_PTR_NOTNULL(tc, recvbuf);
+    ogs_pkbuf_free(recvbuf);
+
     /* Send eNB Status Transfer */
     sendbuf = test_s1ap_build_enb_status_transfer(test_ue);
     ABTS_PTR_NOTNULL(tc, sendbuf);
     rv = testenb_s1ap_send(s1ap1, sendbuf);
     ABTS_INT_EQUAL(tc, OGS_OK, rv);
diff --git a/tests/sctp/abts-main.c b/tests/sctp/abts-main.c
index 7092f8a266..2224ad3505 100644
--- a/tests/sctp/abts-main.c
+++ b/tests/sctp/abts-main.c
@@ -43,11 +43,11 @@ int main(int argc, const char *const argv[])
     ogs_getopt_t options;
     struct {
         char *log_level;
         char *domain_mask;
     } optarg;
-    const char *argv_out[argc+2]; /* '-e error' is always added */
+    const char *argv_out[argc+3]; /* '-e error' is always added */
     
     abts_suite *suite = NULL;
     ogs_pkbuf_config_t config;
 
     rv = abts_main(argc, argv, argv_out);
diff --git a/tests/unit/abts-main.c b/tests/unit/abts-main.c
index 9afbf8c4a1..299f3939f0 100644
--- a/tests/unit/abts-main.c
+++ b/tests/unit/abts-main.c
@@ -65,11 +65,11 @@ int main(int argc, const char *const argv[])
     ogs_getopt_t options;
     struct {
         char *log_level;
         char *domain_mask;
     } optarg;
-    const char *argv_out[argc+2]; /* '-e error' is always added */
+    const char *argv_out[argc+3]; /* '-e error' is always added */
     
     abts_suite *suite = NULL;
     ogs_pkbuf_config_t config;
 
     rv = abts_main(argc, argv, argv_out);

Vulnerable code:     const char *argv_out[argc];
    for (i = 0; argv[i]; i++) {
    for (i = 0; argv[i]; i++) {
    for (i = 0; argv[i]; i++) {
    const char *argv_out[argc+4], *new_argv[argc+4];
            &test_self()->nr_served_tai[index].list2.tai[0], sizeof(ogs_5gs_tai_t));

        ogs_fatal("Not implmented EPC Indirect Tunnel");
        ogs_assert_if_reached();
    int i, j;
    SupportedTAItem = CALLOC(1, sizeof(NGAP_SupportedTAItem_t));
        ogs_asn_uint24_to_OCTET_STRING(
            test_self()->nr_served_tai[0].list2.tai[0].tac,
            &SupportedTAItem->tAC);
        ogs_asn_uint24_to_OCTET_STRING(
            test_self()->nr_served_tai[0].list0.tai[0].tac[0],
                &SupportedTAItem->tAC);
    for (i = 0; i < test_self()->num_of_plmn_support; i++) {
        plmn_id = &test_self()->plmn_support[i].plmn_id;
        BroadcastPLMNItem = CALLOC(1, sizeof(NGAP_BroadcastPLMNItem_t));
        ogs_asn_buffer_to_OCTET_STRING(
                plmn_id, OGS_PLMN_ID_LEN, &BroadcastPLMNItem->pLMNIdentity);
        for (j = 0; j < test_self()->plmn_support[i].num_of_s_nssai; j++) {
            ogs_s_nssai_t *s_nssai = &test_self()->plmn_support[i].s_nssai[j];
            SliceSupportItem = CALLOC(1, sizeof(NGAP_SliceSupportItem_t));
            ogs_asn_uint8_to_OCTET_STRING(s_nssai->sst,
                    &SliceSupportItem->s_NSSAI.sST);
            if (s_nssai->sd.v != OGS_S_NSSAI_NO_SD_VALUE) {
                SliceSupportItem->s_NSSAI.sD = CALLOC(1, sizeof(NGAP_SD_t));
                ogs_asn_uint24_to_OCTET_STRING(
                        s_nssai->sd, SliceSupportItem->s_NSSAI.sD);
            ASN_SEQUENCE_ADD(&BroadcastPLMNItem->tAISliceSupportList.list,
                            SliceSupportItem);
        ASN_SEQUENCE_ADD(&SupportedTAItem->broadcastPLMNList.list,
                BroadcastPLMNItem);
    ASN_SEQUENCE_ADD(&SupportedTAList->list, SupportedTAItem);

    int i, j;
        SupportedTAItem = CALLOC(1, sizeof(NGAP_SupportedTAItem_t));
            ogs_asn_uint24_to_OCTET_STRING(
                test_self()->nr_served_tai[0].list2.tai[0].tac,
                &SupportedTAItem->tAC);
            ogs_asn_uint24_to_OCTET_STRING(
                test_self()->nr_served_tai[0].list0.tai[0].tac[0],
                    &SupportedTAItem->tAC);
        for (i = 0; i < test_self()->num_of_plmn_support; i++) {
            plmn_id = &test_self()->plmn_support[i].plmn_id;

            BroadcastPLMNItem = CALLOC(1, sizeof(NGAP_BroadcastPLMNItem_t));

            ogs_asn_buffer_to_OCTET_STRING(
                    plmn_id, OGS_PLMN_ID_LEN, &BroadcastPLMNItem->pLMNIdentity);

            for (j = 0; j < test_self()->plmn_support[i].num_of_s_nssai; j++) {
                ogs_s_nssai_t *s_nssai =
                    &test_self()->plmn_support[i].s_nssai[j];

                SliceSupportItem = CALLOC(1, sizeof(NGAP_SliceSupportItem_t));
                ogs_asn_uint8_to_OCTET_STRING(s_nssai->sst,
                        &SliceSupportItem->s_NSSAI.sST);
                if (s_nssai->sd.v != OGS_S_NSSAI_NO_SD_VALUE) {
                    SliceSupportItem->s_NSSAI.sD = CALLOC(1, sizeof(NGAP_SD_t));
                    ogs_asn_uint24_to_OCTET_STRING(
                            s_nssai->sd, SliceSupportItem->s_NSSAI.sD);
                ASN_SEQUENCE_ADD(&BroadcastPLMNItem->tAISliceSupportList.list,
                                SliceSupportItem);
            ASN_SEQUENCE_ADD(&SupportedTAItem->broadcastPLMNList.list,
                    BroadcastPLMNItem);

        ASN_SEQUENCE_ADD(&SupportedTAList->list, SupportedTAItem);
    const char *argv_out[argc+2]; /* '-e error' is always added */
    const char *argv_out[argc+2]; /* '-e error' is always added */
    const char *argv_out[argc+2]; /* '-e error' is always added */
    const char *argv_out[argc+2]; /* '-e error' is always added */
Fixed code:     const char *argv_out[argc+1];
    for (i = 0; argv[i] && i < OGS_ARG_MAX-3; i++) {
    for (i = 0; argv[i] && i < OGS_ARG_MAX-3; i++) {
    for (i = 0; argv[i] && i < OGS_ARG_MAX-3; i++) {
    const char *argv_out[argc+5], *new_argv[argc+5];
            &test_self()->nr_served_tai[index].list2.tai[0],
            sizeof(ogs_5gs_tai_t));
    struct {
        /* Indirect Forwarding */
        uint32_t dl_teid;
        ogs_ip_t dl_ip;
        uint32_t ul_teid;
        ogs_ip_t ul_ip;
    } handover;
        gtp_hdesc.teid = bearer->handover.ul_teid;
    int i, j, k, num = 0;
        num = test_self()->nr_served_tai[0].list2.num;
        num = test_self()->nr_served_tai[0].list0.tai[0].num;
    for (i = 0; i < num; i++) {
        SupportedTAItem = CALLOC(1, sizeof(NGAP_SupportedTAItem_t));
        if (test_self()->nr_served_tai[0].list2.num)
            ogs_asn_uint24_to_OCTET_STRING(
                test_self()->nr_served_tai[0].list2.tai[i].tac,
                &SupportedTAItem->tAC);
        else if (test_self()->nr_served_tai[0].list0.tai[0].num)
            ogs_asn_uint24_to_OCTET_STRING(
                test_self()->nr_served_tai[0].list0.tai[0].tac[i],
                    &SupportedTAItem->tAC);
        else
            ogs_assert_if_reached();
        for (j = 0; j < test_self()->num_of_plmn_support; j++) {
            plmn_id = &test_self()->plmn_support[j].plmn_id;
            BroadcastPLMNItem = CALLOC(1, sizeof(NGAP_BroadcastPLMNItem_t));
            ogs_asn_buffer_to_OCTET_STRING(
                    plmn_id, OGS_PLMN_ID_LEN, &BroadcastPLMNItem->pLMNIdentity);
            for (k = 0; k < test_self()->plmn_support[j].num_of_s_nssai; k++) {
                ogs_s_nssai_t *s_nssai =
                    &test_self()->plmn_support[j].s_nssai[k];

                SliceSupportItem = CALLOC(1, sizeof(NGAP_SliceSupportItem_t));
                ogs_asn_uint8_to_OCTET_STRING(s_nssai->sst,
                        &SliceSupportItem->s_NSSAI.sST);
                if (s_nssai->sd.v != OGS_S_NSSAI_NO_SD_VALUE) {
                    SliceSupportItem->s_NSSAI.sD = CALLOC(1, sizeof(NGAP_SD_t));
                    ogs_asn_uint24_to_OCTET_STRING(
                            s_nssai->sd, SliceSupportItem->s_NSSAI.sD);
                }

                ASN_SEQUENCE_ADD(&BroadcastPLMNItem->tAISliceSupportList.list,
                                SliceSupportItem);
            ASN_SEQUENCE_ADD(&SupportedTAItem->broadcastPLMNList.list,
                    BroadcastPLMNItem);
        ASN_SEQUENCE_ADD(&SupportedTAList->list, SupportedTAItem);
    int i, j, k, num;
            num = test_self()->nr_served_tai[0].list2.num;
            num = test_self()->nr_served_tai[0].list0.tai[0].num;
        for (i = 0; i < num; i++) {
            SupportedTAItem = CALLOC(1, sizeof(NGAP_SupportedTAItem_t));
            if (test_self()->nr_served_tai[0].list2.num)
                ogs_asn_uint24_to_OCTET_STRING(
                    test_self()->nr_served_tai[0].list2.tai[i].tac,
                    &SupportedTAItem->tAC);
            else if (test_self()->nr_served_tai[0].list0.tai[0].num)
                ogs_asn_uint24_to_OCTET_STRING(
                    test_self()->nr_served_tai[0].list0.tai[0].tac[i],
                        &SupportedTAItem->tAC);
            else
                ogs_assert_if_reached();

            for (j = 0; j < test_self()->num_of_plmn_support; j++) {
                plmn_id = &test_self()->plmn_support[j].plmn_id;

                BroadcastPLMNItem = CALLOC(1, sizeof(NGAP_BroadcastPLMNItem_t));

                ogs_asn_buffer_to_OCTET_STRING(
                        plmn_id, OGS_PLMN_ID_LEN,
                        &BroadcastPLMNItem->pLMNIdentity);

                for (k = 0; k < test_self()->plmn_support[j].num_of_s_nssai;
                        k++) {
                    ogs_s_nssai_t *s_nssai =
                        &test_self()->plmn_support[j].s_nssai[k];

                    SliceSupportItem = CALLOC(1,
                            sizeof(NGAP_SliceSupportItem_t));
                    ogs_asn_uint8_to_OCTET_STRING(s_nssai->sst,
                            &SliceSupportItem->s_NSSAI.sST);
                    if (s_nssai->sd.v != OGS_S_NSSAI_NO_SD_VALUE) {
                        SliceSupportItem->s_NSSAI.sD = CALLOC(
                                1, sizeof(NGAP_SD_t));
                        ogs_asn_uint24_to_OCTET_STRING(
                                s_nssai->sd, SliceSupportItem->s_NSSAI.sD);
                    }

                    ASN_SEQUENCE_ADD(
                            &BroadcastPLMNItem->tAISliceSupportList.list,
                            SliceSupportItem);
                ASN_SEQUENCE_ADD(&SupportedTAItem->broadcastPLMNList.list,
                        BroadcastPLMNItem);
            ASN_SEQUENCE_ADD(&SupportedTAList->list, SupportedTAItem);
    test_bearer_t *bearer = NULL;
    S1AP_E_RABSubjecttoDataForwardingList_t
        *E_RABSubjecttoDataForwardingList = NULL;
        case S1AP_ProtocolIE_ID_id_E_RABSubjecttoDataForwardingList:
            E_RABSubjecttoDataForwardingList =
                &ie->value.choice.E_RABSubjecttoDataForwardingList;
            break;

    if (E_RABSubjecttoDataForwardingList) {
        for (i = 0; i < E_RABSubjecttoDataForwardingList->list.count; i++) {
            S1AP_E_RABDataForwardingItemIEs_t *ie = NULL;
            S1AP_E_RABDataForwardingItem_t *e_rab = NULL;

            ie = (S1AP_E_RABDataForwardingItemIEs_t *)
                    E_RABSubjecttoDataForwardingList->list.array[i];
            ogs_assert(ie);
            e_rab = &ie->value.choice.E_RABDataForwardingItem;

            bearer = test_bearer_find_by_ue_ebi(test_ue, e_rab->e_RAB_ID);
            ogs_assert(bearer);

            if (e_rab->dL_gTP_TEID) {
                memcpy(&bearer->handover.dl_teid, e_rab->dL_gTP_TEID->buf,
                        sizeof(bearer->handover.dl_teid));
                bearer->handover.dl_teid = be32toh(bearer->handover.dl_teid);
            }
            if (e_rab->dL_transportLayerAddress) {
                ogs_assert(OGS_OK ==
                        ogs_asn_BIT_STRING_to_ip(
                            e_rab->dL_transportLayerAddress,
                            &bearer->handover.dl_ip));
            }
            if (e_rab->uL_GTP_TEID) {
                memcpy(&bearer->handover.ul_teid, e_rab->uL_GTP_TEID->buf,
                        sizeof(bearer->handover.ul_teid));
                bearer->handover.ul_teid = be32toh(bearer->handover.ul_teid);
            }
            if (e_rab->uL_TransportLayerAddress) {
                ogs_assert(OGS_OK ==
                        ogs_asn_BIT_STRING_to_ip(
                            e_rab->uL_TransportLayerAddress,
                            &bearer->handover.ul_ip));
            }
        }
    }
    const char *argv_out[argc+3]; /* '-e error' is always added */
    const char *argv_out[argc+3]; /* '-e error' is always added */
    ogs_pkbuf_t *pkbuf;
    /* Send GTP-U ICMP Packet */
    bearer = test_bearer_find_by_ue_ebi(test_ue, 5);
    ogs_assert(bearer);
    rv = test_gtpu_send_ping(gtpu1, bearer, TEST_PING_IPV4);
    ABTS_INT_EQUAL(tc, OGS_OK, rv);

    /* Receive GTP-U ICMP Packet */
    recvbuf = test_gtpu_read(gtpu1);
    ABTS_PTR_NOTNULL(tc, recvbuf);

    /* Copy ICMP Packet */
    pkbuf = ogs_pkbuf_alloc(NULL, 200);
    ogs_assert(pkbuf);
    ogs_pkbuf_reserve(pkbuf, OGS_GTPV1U_5GC_HEADER_LEN);
    ogs_pkbuf_put(pkbuf, 200-OGS_GTPV1U_5GC_HEADER_LEN);
    memset(pkbuf->data, 0, pkbuf->len);
    memcpy(pkbuf->data, recvbuf->data + 8, recvbuf->len - 8);

    ogs_pkbuf_free(recvbuf);

    /* Send GTP-U Packet with Indirect Data Forwarding */
    rv = test_gtpu_send_indirect_data_forwarding(gtpu1, bearer, pkbuf);
    ABTS_INT_EQUAL(tc, OGS_OK, rv);

    /* Receive GTP-U ICMP Packet */
    recvbuf = testgnb_gtpu_read(gtpu2);
    ABTS_PTR_NOTNULL(tc, recvbuf);
    ogs_pkbuf_free(recvbuf);

    const char *argv_out[argc+3]; /* '-e error' is always added */
    const char *argv_out[argc+3]; /* '-e error' is always added */