forked from acouzens/open5gs
[SMF] Fix Gx/Gy assert() if more than 64 CCRs are sent
The current code uses the cc request number as an index to the transaction array (xact/xact_data). Since cc request number is a 32 bit integer this is unfeasible for longer sessions and if more than a handful of messages are exchanged per session. The array size was already increased in #2038 which simply delays the issue. Furthermore, the current code asserts that cc_request_number is <= MAX_CC_REQUEST_NUMBER which leads to an out-of-bounds write if cc_request_number == MAX_CC_REQUEST_NUMBER. Instead use a smaller array and index into it using cc_request_number % array size. More than 2 requests should never be in flight at any one time (initial or update request together with a termination request) so an array size of 4 should be fine.
This commit is contained in:
parent
93bcd7fda7
commit
ef60207c1e
|
@ -28,9 +28,12 @@ struct sess_state {
|
||||||
|
|
||||||
os0_t peer_host; /* Peer Host */
|
os0_t peer_host; /* Peer Host */
|
||||||
|
|
||||||
#define MAX_CC_REQUEST_NUMBER 64
|
#define NUM_CC_REQUEST_SLOT 4
|
||||||
smf_sess_t *sess;
|
smf_sess_t *sess;
|
||||||
ogs_gtp_xact_t *xact[MAX_CC_REQUEST_NUMBER];
|
struct {
|
||||||
|
uint32_t cc_req_no;
|
||||||
|
ogs_gtp_xact_t *ptr;
|
||||||
|
} xact_data[NUM_CC_REQUEST_SLOT];
|
||||||
|
|
||||||
uint32_t cc_request_type;
|
uint32_t cc_request_type;
|
||||||
uint32_t cc_request_number;
|
uint32_t cc_request_number;
|
||||||
|
@ -103,6 +106,7 @@ void smf_gx_send_ccr(smf_sess_t *sess, ogs_gtp_xact_t *xact,
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
struct sockaddr_in6 sin6;
|
struct sockaddr_in6 sin6;
|
||||||
uint32_t charging_id;
|
uint32_t charging_id;
|
||||||
|
uint32_t req_slot;
|
||||||
|
|
||||||
ogs_assert(sess);
|
ogs_assert(sess);
|
||||||
|
|
||||||
|
@ -191,11 +195,12 @@ void smf_gx_send_ccr(smf_sess_t *sess, ogs_gtp_xact_t *xact,
|
||||||
|
|
||||||
ogs_debug(" CC Request Type[%d] Number[%d]",
|
ogs_debug(" CC Request Type[%d] Number[%d]",
|
||||||
sess_data->cc_request_type, sess_data->cc_request_number);
|
sess_data->cc_request_type, sess_data->cc_request_number);
|
||||||
ogs_assert(sess_data->cc_request_number <= MAX_CC_REQUEST_NUMBER);
|
|
||||||
|
|
||||||
/* Update session state */
|
/* Update session state */
|
||||||
sess_data->sess = sess;
|
sess_data->sess = sess;
|
||||||
sess_data->xact[sess_data->cc_request_number] = xact;
|
req_slot = sess_data->cc_request_number % NUM_CC_REQUEST_SLOT;
|
||||||
|
sess_data->xact_data[req_slot].ptr = xact;
|
||||||
|
sess_data->xact_data[req_slot].cc_req_no = sess_data->cc_request_number;
|
||||||
|
|
||||||
/* Set Origin-Host & Origin-Realm */
|
/* Set Origin-Host & Origin-Realm */
|
||||||
ret = fd_msg_add_origin(req, 0);
|
ret = fd_msg_add_origin(req, 0);
|
||||||
|
@ -713,7 +718,7 @@ static void smf_gx_cca_cb(void *data, struct msg **msg)
|
||||||
ogs_gtp_xact_t *xact = NULL;
|
ogs_gtp_xact_t *xact = NULL;
|
||||||
smf_sess_t *sess = NULL;
|
smf_sess_t *sess = NULL;
|
||||||
ogs_diam_gx_message_t *gx_message = NULL;
|
ogs_diam_gx_message_t *gx_message = NULL;
|
||||||
uint32_t cc_request_number = 0;
|
uint32_t req_slot, cc_request_number = 0;
|
||||||
|
|
||||||
ogs_debug("[Credit-Control-Answer]");
|
ogs_debug("[Credit-Control-Answer]");
|
||||||
|
|
||||||
|
@ -755,11 +760,13 @@ static void smf_gx_cca_cb(void *data, struct msg **msg)
|
||||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||||
ogs_assert(ret == 0);
|
ogs_assert(ret == 0);
|
||||||
cc_request_number = hdr->avp_value->i32;
|
cc_request_number = hdr->avp_value->i32;
|
||||||
|
req_slot = cc_request_number % NUM_CC_REQUEST_SLOT;
|
||||||
|
|
||||||
ogs_debug(" CC-Request-Number[%d]", cc_request_number);
|
ogs_debug(" CC-Request-Number[%d]", cc_request_number);
|
||||||
|
|
||||||
xact = sess_data->xact[cc_request_number];
|
xact = sess_data->xact_data[req_slot].ptr;
|
||||||
sess = sess_data->sess;
|
sess = sess_data->sess;
|
||||||
|
ogs_assert(sess_data->xact_data[req_slot].cc_req_no == cc_request_number);
|
||||||
ogs_assert(sess);
|
ogs_assert(sess);
|
||||||
|
|
||||||
gx_message = ogs_calloc(1, sizeof(ogs_diam_gx_message_t));
|
gx_message = ogs_calloc(1, sizeof(ogs_diam_gx_message_t));
|
||||||
|
|
|
@ -29,12 +29,14 @@ struct sess_state {
|
||||||
|
|
||||||
os0_t peer_host; /* Peer Host */
|
os0_t peer_host; /* Peer Host */
|
||||||
|
|
||||||
#define MAX_CC_REQUEST_NUMBER 64
|
#define NUM_CC_REQUEST_SLOT 4
|
||||||
|
|
||||||
smf_sess_t *sess;
|
smf_sess_t *sess;
|
||||||
struct {
|
struct {
|
||||||
|
uint32_t cc_req_no;
|
||||||
bool pfcp;
|
bool pfcp;
|
||||||
void *ptr; /* INITIAL: ogs_gtp_xact_t, UPDATE: ogs_pfcp_xact_t */
|
void *ptr; /* INITIAL: ogs_gtp_xact_t, UPDATE: ogs_pfcp_xact_t */
|
||||||
} xact_data[MAX_CC_REQUEST_NUMBER];
|
} xact_data[NUM_CC_REQUEST_SLOT];
|
||||||
uint32_t cc_request_type;
|
uint32_t cc_request_type;
|
||||||
uint32_t cc_request_number;
|
uint32_t cc_request_number;
|
||||||
|
|
||||||
|
@ -567,7 +569,7 @@ void smf_gy_send_ccr(smf_sess_t *sess, void *xact,
|
||||||
struct session *session = NULL;
|
struct session *session = NULL;
|
||||||
int new;
|
int new;
|
||||||
const char *service_context_id = "32251@3gpp.org";
|
const char *service_context_id = "32251@3gpp.org";
|
||||||
uint32_t timestamp;
|
uint32_t timestamp, req_slot;
|
||||||
|
|
||||||
ogs_assert(xact);
|
ogs_assert(xact);
|
||||||
ogs_assert(sess);
|
ogs_assert(sess);
|
||||||
|
@ -657,15 +659,16 @@ void smf_gy_send_ccr(smf_sess_t *sess, void *xact,
|
||||||
|
|
||||||
ogs_debug(" CC Request Type[%d] Number[%d]",
|
ogs_debug(" CC Request Type[%d] Number[%d]",
|
||||||
sess_data->cc_request_type, sess_data->cc_request_number);
|
sess_data->cc_request_type, sess_data->cc_request_number);
|
||||||
ogs_assert(sess_data->cc_request_number <= MAX_CC_REQUEST_NUMBER);
|
|
||||||
|
|
||||||
/* Update session state */
|
/* Update session state */
|
||||||
sess_data->sess = sess;
|
sess_data->sess = sess;
|
||||||
|
req_slot = sess_data->cc_request_number % NUM_CC_REQUEST_SLOT;
|
||||||
if (cc_request_type == OGS_DIAM_GY_CC_REQUEST_TYPE_UPDATE_REQUEST)
|
if (cc_request_type == OGS_DIAM_GY_CC_REQUEST_TYPE_UPDATE_REQUEST)
|
||||||
sess_data->xact_data[sess_data->cc_request_number].pfcp = true;
|
sess_data->xact_data[req_slot].pfcp = true;
|
||||||
else
|
else
|
||||||
sess_data->xact_data[sess_data->cc_request_number].pfcp = false;
|
sess_data->xact_data[req_slot].pfcp = false;
|
||||||
sess_data->xact_data[sess_data->cc_request_number].ptr = xact;
|
sess_data->xact_data[req_slot].cc_req_no = sess_data->cc_request_number;
|
||||||
|
sess_data->xact_data[req_slot].ptr = xact;
|
||||||
|
|
||||||
/* Origin-Host & Origin-Realm */
|
/* Origin-Host & Origin-Realm */
|
||||||
ret = fd_msg_add_origin(req, 0);
|
ret = fd_msg_add_origin(req, 0);
|
||||||
|
@ -902,7 +905,7 @@ static void smf_gy_cca_cb(void *data, struct msg **msg)
|
||||||
void *xact = NULL;
|
void *xact = NULL;
|
||||||
smf_sess_t *sess = NULL;
|
smf_sess_t *sess = NULL;
|
||||||
ogs_diam_gy_message_t *gy_message = NULL;
|
ogs_diam_gy_message_t *gy_message = NULL;
|
||||||
uint32_t cc_request_number = 0;
|
uint32_t req_slot, cc_request_number = 0;
|
||||||
|
|
||||||
ogs_debug("[Gy][Credit-Control-Answer]");
|
ogs_debug("[Gy][Credit-Control-Answer]");
|
||||||
|
|
||||||
|
@ -944,11 +947,12 @@ static void smf_gy_cca_cb(void *data, struct msg **msg)
|
||||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||||
ogs_assert(ret == 0);
|
ogs_assert(ret == 0);
|
||||||
cc_request_number = hdr->avp_value->i32;
|
cc_request_number = hdr->avp_value->i32;
|
||||||
|
req_slot = cc_request_number % NUM_CC_REQUEST_SLOT;
|
||||||
|
|
||||||
ogs_debug(" CC-Request-Number[%d]", cc_request_number);
|
ogs_debug(" CC-Request-Number[%d]", cc_request_number);
|
||||||
|
|
||||||
xact = sess_data->xact_data[cc_request_number].ptr;
|
xact = sess_data->xact_data[req_slot].ptr;
|
||||||
ogs_assert(xact);
|
ogs_assert(sess_data->xact_data[req_slot].cc_req_no == cc_request_number);
|
||||||
sess = sess_data->sess;
|
sess = sess_data->sess;
|
||||||
ogs_assert(sess);
|
ogs_assert(sess);
|
||||||
|
|
||||||
|
@ -1106,10 +1110,10 @@ out:
|
||||||
e->sess = sess;
|
e->sess = sess;
|
||||||
e->gy_message = gy_message;
|
e->gy_message = gy_message;
|
||||||
if (gy_message->cc_request_type == OGS_DIAM_GY_CC_REQUEST_TYPE_UPDATE_REQUEST) {
|
if (gy_message->cc_request_type == OGS_DIAM_GY_CC_REQUEST_TYPE_UPDATE_REQUEST) {
|
||||||
ogs_assert(sess_data->xact_data[sess_data->cc_request_number].pfcp == true);
|
ogs_assert(sess_data->xact_data[req_slot].pfcp == true);
|
||||||
e->pfcp_xact = xact;
|
e->pfcp_xact = xact;
|
||||||
} else {
|
} else {
|
||||||
ogs_assert(sess_data->xact_data[sess_data->cc_request_number].pfcp == false);
|
ogs_assert(sess_data->xact_data[req_slot].pfcp == false);
|
||||||
e->gtp_xact = xact;
|
e->gtp_xact = xact;
|
||||||
}
|
}
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
|
|
Loading…
Reference in New Issue