From acb4db5dd1074e19968f8fd5664d94e1e761d71c Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Wed, 28 Jul 2021 14:00:03 +0900 Subject: [PATCH] Fix the crash when number of flow > 8 (#1108) --- lib/core/ogs-3gpp-types.h | 5 +- lib/pfcp/build.c | 10 ++-- lib/pfcp/context.c | 2 +- lib/pfcp/context.h | 3 +- lib/pfcp/handler.c | 4 +- lib/sbi/nnrf-handler.c | 2 +- src/smf/context.c | 14 ++--- src/smf/context.h | 2 - src/smf/gx-path.c | 112 ++++++++++++++++++++------------------ 9 files changed, 79 insertions(+), 75 deletions(-) diff --git a/lib/core/ogs-3gpp-types.h b/lib/core/ogs-3gpp-types.h index b720b1416..fa49aff40 100644 --- a/lib/core/ogs-3gpp-types.h +++ b/lib/core/ogs-3gpp-types.h @@ -32,6 +32,9 @@ extern "C" { #define OGS_MAX_NUM_OF_BEARER 4 /* Num of Bearer per Session */ #define OGS_MAX_NUM_OF_PACKET_BUFFER 64 /* Num of PacketBuffer per UE */ +/* Num of Flow per Bearer or PCC Rule or PDR */ +#define OGS_MAX_NUM_OF_FLOW 8 + /* Num of PacketFilter per Bearer(GTP) or QoS(NAS-5GS) */ #define OGS_MAX_NUM_OF_PACKET_FILTER 16 @@ -336,8 +339,6 @@ typedef struct ogs_pcc_rule_s { char *id; /* 5GC */ char *name; /* EPC */ -/* Num of Flow per PCC Rule */ -#define OGS_MAX_NUM_OF_FLOW 8 ogs_flow_t flow[OGS_MAX_NUM_OF_FLOW]; int num_of_flow; diff --git a/lib/pfcp/build.c b/lib/pfcp/build.c index 2cb386fb9..dedc961db 100644 --- a/lib/pfcp/build.c +++ b/lib/pfcp/build.c @@ -238,7 +238,7 @@ ogs_pkbuf_t *ogs_pfcp_up_build_association_setup_response(uint8_t type, static struct { ogs_pfcp_f_teid_t f_teid; char dnn[OGS_MAX_DNN_LEN]; - char *sdf_filter[OGS_PFCP_MAX_NUM_OF_RULE]; + char *sdf_filter[OGS_MAX_NUM_OF_FLOW]; } pdrbuf[OGS_MAX_NUM_OF_PDR]; void ogs_pfcp_pdrbuf_init(void) @@ -250,7 +250,7 @@ void ogs_pfcp_pdrbuf_clear(void) { int i, j; for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) { - for (j = 0; j < OGS_PFCP_MAX_NUM_OF_RULE; j++) { + for (j = 0; j < OGS_MAX_NUM_OF_FLOW; j++) { if (pdrbuf[i].sdf_filter[j]) ogs_free(pdrbuf[i].sdf_filter[j]); } @@ -261,7 +261,7 @@ void ogs_pfcp_build_create_pdr( ogs_pfcp_tlv_create_pdr_t *message, int i, ogs_pfcp_pdr_t *pdr) { ogs_pfcp_far_t *far = NULL; - ogs_pfcp_sdf_filter_t pfcp_sdf_filter[OGS_PFCP_MAX_NUM_OF_RULE]; + ogs_pfcp_sdf_filter_t pfcp_sdf_filter[OGS_MAX_NUM_OF_FLOW]; int j = 0; int len = 0; @@ -293,6 +293,7 @@ void ogs_pfcp_build_create_pdr( } memset(pfcp_sdf_filter, 0, sizeof(pfcp_sdf_filter)); + ogs_assert(pdr->num_of_flow <= OGS_MAX_NUM_OF_FLOW); for (j = 0; j < pdr->num_of_flow; j++) { pfcp_sdf_filter[j].fd = 1; pfcp_sdf_filter[j].flow_description_len = @@ -376,7 +377,7 @@ void ogs_pfcp_build_created_pdr( void ogs_pfcp_build_update_pdr( ogs_pfcp_tlv_update_pdr_t *message, int i, ogs_pfcp_pdr_t *pdr) { - ogs_pfcp_sdf_filter_t pfcp_sdf_filter[OGS_PFCP_MAX_NUM_OF_RULE]; + ogs_pfcp_sdf_filter_t pfcp_sdf_filter[OGS_MAX_NUM_OF_FLOW]; int j = 0; int len = 0; @@ -399,6 +400,7 @@ void ogs_pfcp_build_update_pdr( } memset(pfcp_sdf_filter, 0, sizeof(pfcp_sdf_filter)); + ogs_assert(pdr->num_of_flow <= OGS_MAX_NUM_OF_FLOW); for (j = 0; j < pdr->num_of_flow; j++) { pfcp_sdf_filter[j].fd = 1; pfcp_sdf_filter[j].flow_description_len = diff --git a/lib/pfcp/context.c b/lib/pfcp/context.c index 6600ab200..14e4a10a3 100644 --- a/lib/pfcp/context.c +++ b/lib/pfcp/context.c @@ -79,7 +79,7 @@ void ogs_pfcp_context_init(void) ogs_app()->pool.sess * OGS_MAX_NUM_OF_BAR); ogs_pool_init(&ogs_pfcp_rule_pool, - ogs_app()->pool.sess * OGS_PFCP_MAX_NUM_OF_RULE); + ogs_app()->pool.sess * OGS_MAX_NUM_OF_PDR * OGS_MAX_NUM_OF_FLOW); ogs_pool_init(&ogs_pfcp_dev_pool, OGS_MAX_NUM_OF_DEV); ogs_pool_init(&ogs_pfcp_subnet_pool, OGS_MAX_NUM_OF_SUBNET); diff --git a/lib/pfcp/context.h b/lib/pfcp/context.h index bc2be9fd5..e14ccb03a 100644 --- a/lib/pfcp/context.h +++ b/lib/pfcp/context.h @@ -173,8 +173,7 @@ typedef struct ogs_pfcp_pdr_s { ogs_pfcp_qer_t *qer; int num_of_flow; -#define OGS_PFCP_MAX_NUM_OF_RULE 8 /* Num of Rule per Session */ - char *flow_description[OGS_PFCP_MAX_NUM_OF_RULE]; + char *flow_description[OGS_MAX_NUM_OF_FLOW]; ogs_list_t rule_list; /* Rule List */ diff --git a/lib/pfcp/handler.c b/lib/pfcp/handler.c index 37d499a03..9cccaffd3 100644 --- a/lib/pfcp/handler.c +++ b/lib/pfcp/handler.c @@ -313,7 +313,7 @@ ogs_pfcp_pdr_t *ogs_pfcp_handle_create_pdr(ogs_pfcp_sess_t *sess, ogs_pfcp_rule_remove_all(pdr); - for (i = 0; i < OGS_PFCP_MAX_NUM_OF_RULE; i++) { + for (i = 0; i < OGS_MAX_NUM_OF_FLOW; i++) { ogs_pfcp_sdf_filter_t sdf_filter; ogs_pfcp_rule_t *rule = NULL; ogs_pfcp_rule_t *oppsite_direction_rule = NULL; @@ -558,7 +558,7 @@ ogs_pfcp_pdr_t *ogs_pfcp_handle_update_pdr(ogs_pfcp_sess_t *sess, ogs_pfcp_rule_remove_all(pdr); - for (i = 0; i < OGS_PFCP_MAX_NUM_OF_RULE; i++) { + for (i = 0; i < OGS_MAX_NUM_OF_FLOW; i++) { ogs_pfcp_sdf_filter_t sdf_filter; ogs_pfcp_rule_t *rule = NULL; ogs_pfcp_rule_t *oppsite_direction_rule = NULL; diff --git a/lib/sbi/nnrf-handler.c b/lib/sbi/nnrf-handler.c index 3e45d1957..bac07d040 100644 --- a/lib/sbi/nnrf-handler.c +++ b/lib/sbi/nnrf-handler.c @@ -374,7 +374,7 @@ bool ogs_sbi_nnrf_handle_nf_profile(ogs_sbi_nf_instance_t *nf_instance, } OpenAPI_list_for_each(AllowedNfTypeList, node2) { - OpenAPI_nf_type_e AllowedNfType = (OpenAPI_nf_type_e)node2->data; + OpenAPI_nf_type_e AllowedNfType = (uintptr_t)node2->data; if (!AllowedNfType) continue; diff --git a/src/smf/context.c b/src/smf/context.c index 61b2c5de7..0ca5709f1 100644 --- a/src/smf/context.c +++ b/src/smf/context.c @@ -59,7 +59,7 @@ void smf_context_init(void) ogs_pool_init(&smf_sess_pool, ogs_app()->pool.sess); ogs_pool_init(&smf_bearer_pool, ogs_app()->pool.bearer); - ogs_pool_init(&smf_pf_pool, ogs_app()->pool.bearer * MAX_NUM_OF_PF); + ogs_pool_init(&smf_pf_pool, ogs_app()->pool.bearer * OGS_MAX_NUM_OF_FLOW); self.supi_hash = ogs_hash_make(); ogs_assert(self.supi_hash); @@ -2143,14 +2143,14 @@ smf_pf_t *smf_pf_add(smf_bearer_t *bearer) ogs_assert(pf->identifier_node); pf->identifier = *(pf->identifier_node); - ogs_assert(pf->identifier > 0 && pf->identifier <= MAX_NUM_OF_PF); + ogs_assert(pf->identifier > 0 && pf->identifier <= OGS_MAX_NUM_OF_FLOW); ogs_pool_alloc(&sess->pf_precedence_pool, &pf->precedence_node); ogs_assert(pf->precedence_node); pf->precedence = *(pf->precedence_node); ogs_assert(pf->precedence > 0 && pf->precedence <= - (OGS_MAX_NUM_OF_BEARER * MAX_NUM_OF_PF)); + (OGS_MAX_NUM_OF_BEARER * OGS_MAX_NUM_OF_FLOW)); pf->bearer = bearer; @@ -2427,9 +2427,9 @@ void smf_pf_identifier_pool_init(smf_bearer_t *bearer) ogs_assert(bearer); - ogs_index_init(&bearer->pf_identifier_pool, MAX_NUM_OF_PF); + ogs_index_init(&bearer->pf_identifier_pool, OGS_MAX_NUM_OF_FLOW); - for (i = 1; i <= MAX_NUM_OF_PF; i++) { + for (i = 1; i <= OGS_MAX_NUM_OF_FLOW; i++) { bearer->pf_identifier_pool.array[i-1] = i; } } @@ -2448,9 +2448,9 @@ void smf_pf_precedence_pool_init(smf_sess_t *sess) ogs_assert(sess); ogs_index_init(&sess->pf_precedence_pool, - OGS_MAX_NUM_OF_BEARER * MAX_NUM_OF_PF); + OGS_MAX_NUM_OF_BEARER * OGS_MAX_NUM_OF_FLOW); - for (i = 1; i <= OGS_MAX_NUM_OF_BEARER * MAX_NUM_OF_PF; i++) { + for (i = 1; i <= OGS_MAX_NUM_OF_BEARER * OGS_MAX_NUM_OF_FLOW; i++) { sess->pf_precedence_pool.array[i-1] = i; } } diff --git a/src/smf/context.h b/src/smf/context.h index b547c6716..2a2777f9d 100644 --- a/src/smf/context.h +++ b/src/smf/context.h @@ -177,8 +177,6 @@ typedef struct smf_bearer_s { OGS_POOL(pf_identifier_pool, uint8_t); -#define MAX_NUM_OF_PF 16 /* Num of PacketFilter per Bearer */ - /* Packet Filter List */ ogs_list_t pf_list; ogs_list_t pf_to_add_list; diff --git a/src/smf/gx-path.c b/src/smf/gx-path.c index 64361da6a..2c84577a8 100644 --- a/src/smf/gx-path.c +++ b/src/smf/gx-path.c @@ -880,21 +880,19 @@ static void smf_gx_cca_cb(void *data, struct msg **msg) ogs_assert(ret == 0); switch (hdr->avp_code) { case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_DEFINITION: - pcc_rule = &gx_message->session_data.pcc_rule - [gx_message->session_data.num_of_pcc_rule]; + if (gx_message->session_data.num_of_pcc_rule < + OGS_MAX_NUM_OF_PCC_RULE) { + pcc_rule = &gx_message->session_data.pcc_rule + [gx_message->session_data.num_of_pcc_rule]; - rv = decode_pcc_rule_definition(pcc_rule, avpch1, &error); - ogs_assert(rv == OGS_OK); + rv = decode_pcc_rule_definition( + pcc_rule, avpch1, &error); + ogs_assert(rv == OGS_OK); - pcc_rule->type = OGS_PCC_RULE_TYPE_INSTALL; - gx_message->session_data.num_of_pcc_rule++; - - /* Check for maximum number of flow rules per bearer */ - bearer = smf_bearer_find_by_pcc_rule_name( - sess_data->sess, pcc_rule->name); - if (bearer && - ((ogs_list_count(&bearer->pf_list) + - pcc_rule->num_of_flow) > MAX_NUM_OF_PF)) { + pcc_rule->type = OGS_PCC_RULE_TYPE_INSTALL; + gx_message->session_data.num_of_pcc_rule++; + } else { + ogs_error("Overflow: Number of PCCRule"); error++; } break; @@ -1081,23 +1079,18 @@ static int smf_gx_rar_cb( struct msg **msg, struct avp *avp, ogs_assert(ret == 0); switch(hdr->avp_code) { case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_DEFINITION: - pcc_rule = &gx_message->session_data.pcc_rule - [gx_message->session_data.num_of_pcc_rule]; + if (gx_message->session_data.num_of_pcc_rule < + OGS_MAX_NUM_OF_PCC_RULE) { + pcc_rule = &gx_message->session_data.pcc_rule + [gx_message->session_data.num_of_pcc_rule]; - rv = decode_pcc_rule_definition(pcc_rule, avpch1, NULL); - ogs_assert(rv == OGS_OK); + rv = decode_pcc_rule_definition(pcc_rule, avpch1, NULL); + ogs_assert(rv == OGS_OK); - pcc_rule->type = OGS_PCC_RULE_TYPE_INSTALL; - gx_message->session_data.num_of_pcc_rule++; - - /* Check for maximum number of flow rules per bearer */ - bearer = smf_bearer_find_by_pcc_rule_name( - sess_data->sess, pcc_rule->name); - if (bearer && - ((ogs_list_count(&bearer->pf_list) + - pcc_rule->num_of_flow) > MAX_NUM_OF_PF)) { - result_code = ER_DIAMETER_UNABLE_TO_COMPLY; - goto out; + pcc_rule->type = OGS_PCC_RULE_TYPE_INSTALL; + gx_message->session_data.num_of_pcc_rule++; + } else { + ogs_error("Overflow: Number of PCCRule"); } break; default: @@ -1115,14 +1108,20 @@ static int smf_gx_rar_cb( struct msg **msg, struct avp *avp, ogs_assert(ret == 0); switch (hdr->avp_code) { case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_NAME: - pcc_rule = &gx_message->session_data.pcc_rule - [gx_message->session_data.num_of_pcc_rule]; + if (gx_message->session_data.num_of_pcc_rule < + OGS_MAX_NUM_OF_PCC_RULE) { + pcc_rule = &gx_message->session_data.pcc_rule + [gx_message->session_data.num_of_pcc_rule]; - pcc_rule->name = ogs_strdup((char*)hdr->avp_value->os.data); - ogs_assert(pcc_rule->name); + pcc_rule->name = ogs_strdup( + (char*)hdr->avp_value->os.data); + ogs_assert(pcc_rule->name); - pcc_rule->type = OGS_PCC_RULE_TYPE_REMOVE; - gx_message->session_data.num_of_pcc_rule++; + pcc_rule->type = OGS_PCC_RULE_TYPE_REMOVE; + gx_message->session_data.num_of_pcc_rule++; + } else { + ogs_error("Overflow: Number of PCCRule"); + } break; default: ogs_error("Not supported(%d)", hdr->avp_code); @@ -1286,31 +1285,36 @@ static int decode_pcc_rule_definition( ogs_assert(pcc_rule->name); break; case OGS_DIAM_GX_AVP_CODE_FLOW_INFORMATION: - flow = &pcc_rule->flow[pcc_rule->num_of_flow]; + if (pcc_rule->num_of_flow < OGS_MAX_NUM_OF_FLOW) { + flow = &pcc_rule->flow[pcc_rule->num_of_flow]; - ret = fd_avp_search_avp( - avpch2, ogs_diam_gx_flow_direction, &avpch3); - ogs_assert(ret == 0); - if (avpch3) { - ret = fd_msg_avp_hdr( avpch3, &hdr); + ret = fd_avp_search_avp( + avpch2, ogs_diam_gx_flow_direction, &avpch3); ogs_assert(ret == 0); - flow->direction = hdr->avp_value->i32; - } + if (avpch3) { + ret = fd_msg_avp_hdr( avpch3, &hdr); + ogs_assert(ret == 0); + flow->direction = hdr->avp_value->i32; + } - ret = fd_avp_search_avp( - avpch2, ogs_diam_gx_flow_description, &avpch3); - ogs_assert(ret == 0); - if (avpch3) { - ret = fd_msg_avp_hdr(avpch3, &hdr); + ret = fd_avp_search_avp( + avpch2, ogs_diam_gx_flow_description, &avpch3); ogs_assert(ret == 0); - flow->description = ogs_malloc(hdr->avp_value->os.len+1); - ogs_assert(flow->description); - ogs_cpystrn(flow->description, - (char*)hdr->avp_value->os.data, - hdr->avp_value->os.len+1); - } + if (avpch3) { + ret = fd_msg_avp_hdr(avpch3, &hdr); + ogs_assert(ret == 0); + flow->description = ogs_malloc(hdr->avp_value->os.len+1); + ogs_assert(flow->description); + ogs_cpystrn(flow->description, + (char*)hdr->avp_value->os.data, + hdr->avp_value->os.len+1); + } - pcc_rule->num_of_flow++; + pcc_rule->num_of_flow++; + } else { + ogs_error("Overflow: Num of Flow"); + error++; + } break; case OGS_DIAM_GX_AVP_CODE_FLOW_STATUS: pcc_rule->flow_status = hdr->avp_value->i32;