CVE-2024-40130 (C, published 2024-07-16T19:15Z)
Description: value: open5gs v2.6.4 is vulnerable to Buffer Overflow. via /lib/core/abts.c.
Severity: nan (CVSS v3 base score: )
Weakness: NVD-CWE-noinfo \u2014 Insufficient Information
There is insufficient information about the issue to classify it; details are unkown or unspecified.
Repository: https://github.com/open5gs/open5gs
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 message: Fixed dynamic-stack-buffer-overflow (#2578, #2577)


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 */