Fix the crash when number of flow > 8 (#1108)

This commit is contained in:
Sukchan Lee
2021-07-28 14:00:03 +09:00
parent 3e7d2398a2
commit acb4db5dd1
9 changed files with 79 additions and 75 deletions

View File

@@ -32,6 +32,9 @@ extern "C" {
#define OGS_MAX_NUM_OF_BEARER 4 /* Num of Bearer per Session */ #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 */ #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) */ /* Num of PacketFilter per Bearer(GTP) or QoS(NAS-5GS) */
#define OGS_MAX_NUM_OF_PACKET_FILTER 16 #define OGS_MAX_NUM_OF_PACKET_FILTER 16
@@ -336,8 +339,6 @@ typedef struct ogs_pcc_rule_s {
char *id; /* 5GC */ char *id; /* 5GC */
char *name; /* EPC */ 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]; ogs_flow_t flow[OGS_MAX_NUM_OF_FLOW];
int num_of_flow; int num_of_flow;

View File

@@ -238,7 +238,7 @@ ogs_pkbuf_t *ogs_pfcp_up_build_association_setup_response(uint8_t type,
static struct { static struct {
ogs_pfcp_f_teid_t f_teid; ogs_pfcp_f_teid_t f_teid;
char dnn[OGS_MAX_DNN_LEN]; 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]; } pdrbuf[OGS_MAX_NUM_OF_PDR];
void ogs_pfcp_pdrbuf_init(void) void ogs_pfcp_pdrbuf_init(void)
@@ -250,7 +250,7 @@ void ogs_pfcp_pdrbuf_clear(void)
{ {
int i, j; int i, j;
for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) { 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]) if (pdrbuf[i].sdf_filter[j])
ogs_free(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_tlv_create_pdr_t *message, int i, ogs_pfcp_pdr_t *pdr)
{ {
ogs_pfcp_far_t *far = NULL; 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 j = 0;
int len = 0; int len = 0;
@@ -293,6 +293,7 @@ void ogs_pfcp_build_create_pdr(
} }
memset(pfcp_sdf_filter, 0, sizeof(pfcp_sdf_filter)); 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++) { for (j = 0; j < pdr->num_of_flow; j++) {
pfcp_sdf_filter[j].fd = 1; pfcp_sdf_filter[j].fd = 1;
pfcp_sdf_filter[j].flow_description_len = pfcp_sdf_filter[j].flow_description_len =
@@ -376,7 +377,7 @@ void ogs_pfcp_build_created_pdr(
void ogs_pfcp_build_update_pdr( void ogs_pfcp_build_update_pdr(
ogs_pfcp_tlv_update_pdr_t *message, int i, ogs_pfcp_pdr_t *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 j = 0;
int len = 0; int len = 0;
@@ -399,6 +400,7 @@ void ogs_pfcp_build_update_pdr(
} }
memset(pfcp_sdf_filter, 0, sizeof(pfcp_sdf_filter)); 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++) { for (j = 0; j < pdr->num_of_flow; j++) {
pfcp_sdf_filter[j].fd = 1; pfcp_sdf_filter[j].fd = 1;
pfcp_sdf_filter[j].flow_description_len = pfcp_sdf_filter[j].flow_description_len =

View File

@@ -79,7 +79,7 @@ void ogs_pfcp_context_init(void)
ogs_app()->pool.sess * OGS_MAX_NUM_OF_BAR); ogs_app()->pool.sess * OGS_MAX_NUM_OF_BAR);
ogs_pool_init(&ogs_pfcp_rule_pool, 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_dev_pool, OGS_MAX_NUM_OF_DEV);
ogs_pool_init(&ogs_pfcp_subnet_pool, OGS_MAX_NUM_OF_SUBNET); ogs_pool_init(&ogs_pfcp_subnet_pool, OGS_MAX_NUM_OF_SUBNET);

View File

@@ -173,8 +173,7 @@ typedef struct ogs_pfcp_pdr_s {
ogs_pfcp_qer_t *qer; ogs_pfcp_qer_t *qer;
int num_of_flow; int num_of_flow;
#define OGS_PFCP_MAX_NUM_OF_RULE 8 /* Num of Rule per Session */ char *flow_description[OGS_MAX_NUM_OF_FLOW];
char *flow_description[OGS_PFCP_MAX_NUM_OF_RULE];
ogs_list_t rule_list; /* Rule List */ ogs_list_t rule_list; /* Rule List */

View File

@@ -313,7 +313,7 @@ ogs_pfcp_pdr_t *ogs_pfcp_handle_create_pdr(ogs_pfcp_sess_t *sess,
ogs_pfcp_rule_remove_all(pdr); 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_sdf_filter_t sdf_filter;
ogs_pfcp_rule_t *rule = NULL; ogs_pfcp_rule_t *rule = NULL;
ogs_pfcp_rule_t *oppsite_direction_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); 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_sdf_filter_t sdf_filter;
ogs_pfcp_rule_t *rule = NULL; ogs_pfcp_rule_t *rule = NULL;
ogs_pfcp_rule_t *oppsite_direction_rule = NULL; ogs_pfcp_rule_t *oppsite_direction_rule = NULL;

View File

@@ -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_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; if (!AllowedNfType) continue;

View File

@@ -59,7 +59,7 @@ void smf_context_init(void)
ogs_pool_init(&smf_sess_pool, ogs_app()->pool.sess); ogs_pool_init(&smf_sess_pool, ogs_app()->pool.sess);
ogs_pool_init(&smf_bearer_pool, ogs_app()->pool.bearer); 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(); self.supi_hash = ogs_hash_make();
ogs_assert(self.supi_hash); ogs_assert(self.supi_hash);
@@ -2143,14 +2143,14 @@ smf_pf_t *smf_pf_add(smf_bearer_t *bearer)
ogs_assert(pf->identifier_node); ogs_assert(pf->identifier_node);
pf->identifier = *(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_pool_alloc(&sess->pf_precedence_pool, &pf->precedence_node);
ogs_assert(pf->precedence_node); ogs_assert(pf->precedence_node);
pf->precedence = *(pf->precedence_node); pf->precedence = *(pf->precedence_node);
ogs_assert(pf->precedence > 0 && pf->precedence <= 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; pf->bearer = bearer;
@@ -2427,9 +2427,9 @@ void smf_pf_identifier_pool_init(smf_bearer_t *bearer)
ogs_assert(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; 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_assert(sess);
ogs_index_init(&sess->pf_precedence_pool, 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; sess->pf_precedence_pool.array[i-1] = i;
} }
} }

View File

@@ -177,8 +177,6 @@ typedef struct smf_bearer_s {
OGS_POOL(pf_identifier_pool, uint8_t); OGS_POOL(pf_identifier_pool, uint8_t);
#define MAX_NUM_OF_PF 16 /* Num of PacketFilter per Bearer */
/* Packet Filter List */ /* Packet Filter List */
ogs_list_t pf_list; ogs_list_t pf_list;
ogs_list_t pf_to_add_list; ogs_list_t pf_to_add_list;

View File

@@ -880,21 +880,19 @@ static void smf_gx_cca_cb(void *data, struct msg **msg)
ogs_assert(ret == 0); ogs_assert(ret == 0);
switch (hdr->avp_code) { switch (hdr->avp_code) {
case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_DEFINITION: case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_DEFINITION:
pcc_rule = &gx_message->session_data.pcc_rule if (gx_message->session_data.num_of_pcc_rule <
[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); rv = decode_pcc_rule_definition(
ogs_assert(rv == OGS_OK); pcc_rule, avpch1, &error);
ogs_assert(rv == OGS_OK);
pcc_rule->type = OGS_PCC_RULE_TYPE_INSTALL; pcc_rule->type = OGS_PCC_RULE_TYPE_INSTALL;
gx_message->session_data.num_of_pcc_rule++; gx_message->session_data.num_of_pcc_rule++;
} else {
/* Check for maximum number of flow rules per bearer */ ogs_error("Overflow: Number of PCCRule");
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)) {
error++; error++;
} }
break; break;
@@ -1081,23 +1079,18 @@ static int smf_gx_rar_cb( struct msg **msg, struct avp *avp,
ogs_assert(ret == 0); ogs_assert(ret == 0);
switch(hdr->avp_code) { switch(hdr->avp_code) {
case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_DEFINITION: case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_DEFINITION:
pcc_rule = &gx_message->session_data.pcc_rule if (gx_message->session_data.num_of_pcc_rule <
[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); rv = decode_pcc_rule_definition(pcc_rule, avpch1, NULL);
ogs_assert(rv == OGS_OK); ogs_assert(rv == OGS_OK);
pcc_rule->type = OGS_PCC_RULE_TYPE_INSTALL; pcc_rule->type = OGS_PCC_RULE_TYPE_INSTALL;
gx_message->session_data.num_of_pcc_rule++; gx_message->session_data.num_of_pcc_rule++;
} else {
/* Check for maximum number of flow rules per bearer */ ogs_error("Overflow: Number of PCCRule");
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;
} }
break; break;
default: default:
@@ -1115,14 +1108,20 @@ static int smf_gx_rar_cb( struct msg **msg, struct avp *avp,
ogs_assert(ret == 0); ogs_assert(ret == 0);
switch (hdr->avp_code) { switch (hdr->avp_code) {
case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_NAME: case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_NAME:
pcc_rule = &gx_message->session_data.pcc_rule if (gx_message->session_data.num_of_pcc_rule <
[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); pcc_rule->name = ogs_strdup(
ogs_assert(pcc_rule->name); (char*)hdr->avp_value->os.data);
ogs_assert(pcc_rule->name);
pcc_rule->type = OGS_PCC_RULE_TYPE_REMOVE; pcc_rule->type = OGS_PCC_RULE_TYPE_REMOVE;
gx_message->session_data.num_of_pcc_rule++; gx_message->session_data.num_of_pcc_rule++;
} else {
ogs_error("Overflow: Number of PCCRule");
}
break; break;
default: default:
ogs_error("Not supported(%d)", hdr->avp_code); ogs_error("Not supported(%d)", hdr->avp_code);
@@ -1286,31 +1285,36 @@ static int decode_pcc_rule_definition(
ogs_assert(pcc_rule->name); ogs_assert(pcc_rule->name);
break; break;
case OGS_DIAM_GX_AVP_CODE_FLOW_INFORMATION: 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( ret = fd_avp_search_avp(
avpch2, ogs_diam_gx_flow_direction, &avpch3); avpch2, ogs_diam_gx_flow_direction, &avpch3);
ogs_assert(ret == 0);
if (avpch3) {
ret = fd_msg_avp_hdr( avpch3, &hdr);
ogs_assert(ret == 0); 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( ret = fd_avp_search_avp(
avpch2, ogs_diam_gx_flow_description, &avpch3); avpch2, ogs_diam_gx_flow_description, &avpch3);
ogs_assert(ret == 0);
if (avpch3) {
ret = fd_msg_avp_hdr(avpch3, &hdr);
ogs_assert(ret == 0); ogs_assert(ret == 0);
flow->description = ogs_malloc(hdr->avp_value->os.len+1); if (avpch3) {
ogs_assert(flow->description); ret = fd_msg_avp_hdr(avpch3, &hdr);
ogs_cpystrn(flow->description, ogs_assert(ret == 0);
(char*)hdr->avp_value->os.data, flow->description = ogs_malloc(hdr->avp_value->os.len+1);
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; break;
case OGS_DIAM_GX_AVP_CODE_FLOW_STATUS: case OGS_DIAM_GX_AVP_CODE_FLOW_STATUS:
pcc_rule->flow_status = hdr->avp_value->i32; pcc_rule->flow_status = hdr->avp_value->i32;