Skip to content

Commit

Permalink
[sgwc][smf][no_upstream] check if session is active before dereferenc…
Browse files Browse the repository at this point in the history
…ing (#66)
  • Loading branch information
spencersevilla committed Jan 24, 2024
1 parent 463d8bc commit 240d821
Show file tree
Hide file tree
Showing 13 changed files with 165 additions and 63 deletions.
8 changes: 8 additions & 0 deletions src/sgwc/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,11 @@ sgwc_sess_t *sgwc_sess_add(sgwc_ue_t *sgwc_ue, char *apn)
(long long)ogs_app()->pool.sess);
return NULL;
}

memset(sess, 0, sizeof *sess);

sess->active = true;

ogs_pfcp_pool_init(&sess->pfcp);

/* Set TEID & SEID */
Expand Down Expand Up @@ -443,6 +446,11 @@ int sgwc_sess_remove(sgwc_sess_t *sess)
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);

if (!sess->active) {
ogs_error("sgwc_sess_remove double-free");
}
sess->active = false;

ogs_list_remove(&sgwc_ue->sess_list, sess);

ogs_hash_set(self.sgwc_sxa_seid_hash, &sess->sgwc_sxa_seid,
Expand Down
3 changes: 3 additions & 0 deletions src/sgwc/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ typedef struct sgwc_sess_s {
ogs_pfcp_node_t *pfcp_node;

sgwc_ue_t *sgwc_ue;

bool active;

} sgwc_sess_t;

typedef struct sgwc_bearer_s {
Expand Down
44 changes: 33 additions & 11 deletions src/sgwc/s11-handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ void sgwc_s11_handle_modify_bearer_request(
}

sess = bearer->sess;
ogs_assert(sess);
ogs_assert(sess && sess->active);

ogs_list_for_each_entry(&pfcp_xact_list, pfcp_xact, tmpnode) {
if (sess == pfcp_xact->data) {
Expand Down Expand Up @@ -635,7 +635,7 @@ void sgwc_s11_handle_delete_session_request(

if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
sess = sgwc_sess_find_by_ebi(sgwc_ue, req->linked_eps_bearer_id.u8);
if (!sess) {
if (!sess || !sess->active) {
ogs_error("Unknown EPS Bearer [IMSI:%s, EBI:%d]",
sgwc_ue->imsi_bcd, req->linked_eps_bearer_id.u8);
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
Expand Down Expand Up @@ -675,7 +675,7 @@ void sgwc_s11_handle_delete_session_request(
* Check ALL Context
********************/
ogs_assert(sgwc_ue);
ogs_assert(sess);
ogs_assert(sess && sess->active);
ogs_assert(sess->gnode);
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid);
Expand Down Expand Up @@ -756,7 +756,7 @@ void sgwc_s11_handle_create_bearer_response(

ogs_assert(bearer);
sess = bearer->sess;
ogs_assert(sess);
ogs_assert(sess && sess->active);

rv = ogs_gtp_xact_commit(s11_xact);
ogs_expect(rv == OGS_OK);
Expand Down Expand Up @@ -825,7 +825,7 @@ void sgwc_s11_handle_create_bearer_response(
* Check ALL Context
********************/
ogs_assert(sgwc_ue);
ogs_assert(sess);
ogs_assert(sess && sess->active);
ogs_assert(bearer);

/* Correlate with SGW-S1U-TEID */
Expand Down Expand Up @@ -899,7 +899,6 @@ void sgwc_s11_handle_update_bearer_response(
sgwc_bearer_t *bearer = NULL;
ogs_gtp2_update_bearer_response_t *rsp = NULL;

ogs_assert(sgwc_ue);
ogs_assert(message);
rsp = &message->update_bearer_response;
ogs_assert(rsp);
Expand All @@ -921,11 +920,31 @@ void sgwc_s11_handle_update_bearer_response(

ogs_assert(bearer);
sess = bearer->sess;
ogs_assert(sess);

rv = ogs_gtp_xact_commit(s11_xact);
ogs_expect(rv == OGS_OK);

/************************
* Check SGWC-UE Context
************************/
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;

if (!sgwc_ue) {
ogs_error("No Context in TEID");
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
}

if (!sess || !sess->active) {
ogs_error("No Sess Context");
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
}

if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
return;
}

/*****************************************
* Check Mandatory/Conditional IE Missing
*****************************************/
Expand Down Expand Up @@ -984,7 +1003,7 @@ void sgwc_s11_handle_update_bearer_response(
* Check ALL Context
********************/
ogs_assert(sgwc_ue);
ogs_assert(sess);
ogs_assert(sess && sess->active);

ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid);
Expand Down Expand Up @@ -1044,7 +1063,7 @@ void sgwc_s11_handle_delete_bearer_response(

ogs_assert(bearer);
sess = bearer->sess;
ogs_assert(sess);
ogs_assert(sess && sess->active);

rv = ogs_gtp_xact_commit(s11_xact);
ogs_expect(rv == OGS_OK);
Expand Down Expand Up @@ -1209,14 +1228,17 @@ void sgwc_s11_handle_downlink_data_notification_ack(
bearer = s11_xact->data;
ogs_assert(bearer);
sess = bearer->sess;
ogs_assert(sess);

rv = ogs_gtp_xact_commit(s11_xact);
ogs_expect(rv == OGS_OK);

/************************
* Check SGWC-UE Context
************************/
if (!sess || !sess->active) {
ogs_error("No Sess Context");
}

if (ack->cause.presence) {
ogs_gtp2_cause_t *cause = ack->cause.data;
ogs_assert(cause);
Expand Down Expand Up @@ -1508,7 +1530,7 @@ void sgwc_s11_handle_bearer_resource_command(
********************/
ogs_assert(bearer);
sess = bearer->sess;
ogs_assert(sess);
ogs_assert(sess && sess->active);
ogs_assert(sess->gnode);
ogs_assert(sgwc_ue);

Expand Down
14 changes: 7 additions & 7 deletions src/sgwc/s5c-handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ void sgwc_s5c_handle_create_session_response(
************************/
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;

if (!sess) {
if (!sess || !sess->active) {
ogs_error("No Context in TEID [Cause:%d]", session_cause);
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
} else {
Expand Down Expand Up @@ -354,7 +354,7 @@ void sgwc_s5c_handle_modify_bearer_response(
************************/
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;

if (!sess) {
if (!sess || !sess->active) {
ogs_error("No Context in TEID [Cause:%d]", session_cause);
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
} else {
Expand Down Expand Up @@ -496,7 +496,7 @@ void sgwc_s5c_handle_delete_session_response(
************************/
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;

if (!sess) {
if (!sess || !sess->active) {
ogs_error("No Context in TEID [Cause:%d]", session_cause);
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
} else {
Expand Down Expand Up @@ -578,7 +578,7 @@ void sgwc_s5c_handle_create_bearer_request(
************************/
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;

if (!sess) {
if (!sess || !sess->active) {
ogs_error("No Context in TEID");
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
} else {
Expand Down Expand Up @@ -697,7 +697,7 @@ void sgwc_s5c_handle_update_bearer_request(
************************/
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;

if (!sess) {
if (!sess || !sess->active) {
ogs_error("No Context in TEID");
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
} else {
Expand Down Expand Up @@ -809,7 +809,7 @@ void sgwc_s5c_handle_delete_bearer_request(
************************/
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;

if (!sess) {
if (!sess || !sess->active) {
ogs_error("No Context in TEID");
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
} else {
Expand Down Expand Up @@ -969,7 +969,7 @@ void sgwc_s5c_handle_bearer_resource_failure_indication(
*
* - Session could be deleted before a message is received from SMF.
************************/
if (!sess) {
if (!sess || !sess->active) {
ogs_error("No Context in TEID");
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
} else {
Expand Down
49 changes: 30 additions & 19 deletions src/sgwc/sxa-handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ static void sgwc_sxa_handle_session_reestablishment(
sgwc_sess_t *sess, ogs_pfcp_xact_t *pfcp_xact,
ogs_pfcp_session_establishment_response_t *pfcp_rsp)
{
ogs_assert(sess);
ogs_assert(sess && sess->active);
ogs_assert(pfcp_xact);
ogs_assert(pfcp_rsp);

Expand Down Expand Up @@ -197,7 +197,7 @@ void sgwc_sxa_handle_session_establishment_response(

cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;

if (!sess) {
if (!sess || !sess->active) {
ogs_error("No Context");
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
}
Expand Down Expand Up @@ -277,7 +277,7 @@ void sgwc_sxa_handle_session_establishment_response(
return;
}

ogs_assert(sess);
ogs_assert(sess && sess->active);

ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
Expand Down Expand Up @@ -502,13 +502,19 @@ void sgwc_sxa_handle_session_modification_response(
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;

if (flags & OGS_PFCP_MODIFY_SESSION) {
if (!sess) {
ogs_error("No Context");

if (!sess || !sess->active) {
// sess pointer was expired; can we recover it from xact?
sess = pfcp_xact->data;
ogs_assert(sess);

cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
if (!sess || !sess->active) {
ogs_error("No Context");
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
// send gtp error?
ogs_pfcp_xact_commit(pfcp_xact);
return;
} else {
ogs_warn("sess expired but pfcp_xact->sess active");
}
}

sgwc_ue = sess->sgwc_ue;
Expand All @@ -518,15 +524,20 @@ void sgwc_sxa_handle_session_modification_response(
bearer = pfcp_xact->data;
ogs_assert(bearer);

if (!sess) {
ogs_error("No Context");

if (!sess || !sess->active) {
// sess pointer was expired; can we recover it from bearer?
sess = bearer->sess;
ogs_assert(sess);

cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
if (!sess || !sess->active) {
ogs_error("No Context");
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
// send gtp error?
ogs_pfcp_xact_commit(pfcp_xact);
return;
} else {
ogs_warn("sess expired but bearer->sess active");
}
}

sgwc_ue = bearer->sgwc_ue;
ogs_assert(sgwc_ue);
}
Expand All @@ -551,7 +562,7 @@ void sgwc_sxa_handle_session_modification_response(

OGS_LIST(pdr_to_create_list);

ogs_assert(sess);
ogs_assert(sess && sess->active);

ogs_list_copy(&pdr_to_create_list, &pfcp_xact->pdr_to_create_list);

Expand Down Expand Up @@ -1306,7 +1317,7 @@ void sgwc_sxa_handle_session_deletion_response(

cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;

if (!sess) {
if (!sess || !sess->active) {
ogs_error("No Context");
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
}
Expand Down Expand Up @@ -1375,7 +1386,7 @@ void sgwc_sxa_handle_session_deletion_response(
return;
}

ogs_assert(sess);
ogs_assert(sess && sess->active);
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);

Expand Down Expand Up @@ -1451,7 +1462,7 @@ void sgwc_sxa_handle_session_report_request(
*
* - Session could be deleted before a message is received from SMF.
************************/
if (!sess) {
if (!sess || !sess->active) {
ogs_error("No Context");
cause_value = OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND;
}
Expand All @@ -1468,7 +1479,7 @@ void sgwc_sxa_handle_session_report_request(
return;
}

ogs_assert(sess);
ogs_assert(sess && sess->active);
sgwc_ue = sess->sgwc_ue;
ogs_assert(sgwc_ue);

Expand Down
7 changes: 7 additions & 0 deletions src/smf/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -1257,6 +1257,7 @@ smf_sess_t *smf_sess_add_by_apn(smf_ue_t *smf_ue, char *apn, uint8_t rat_type)
e.sess = sess;
ogs_fsm_init(&sess->sm, smf_gsm_state_initial, smf_gsm_state_final, &e);

sess->active = true;
sess->smf_ue = smf_ue;

ogs_list_add(&smf_ue->sess_list, sess);
Expand Down Expand Up @@ -1471,6 +1472,7 @@ smf_sess_t *smf_sess_add_by_psi(smf_ue_t *smf_ue, uint8_t psi)
e.sess = sess;
ogs_fsm_init(&sess->sm, smf_gsm_state_initial, smf_gsm_state_final, &e);

sess->active = true;
sess->smf_ue = smf_ue;

ogs_list_add(&smf_ue->sess_list, sess);
Expand Down Expand Up @@ -1690,6 +1692,11 @@ void smf_sess_remove(smf_sess_t *sess)

ogs_list_remove(&smf_ue->sess_list, sess);

if (!sess->active) {
ogs_error("smf_sess_remove double-free");
}
sess->active = false;

memset(&e, 0, sizeof(e));
e.sess = sess;
ogs_fsm_fini(&sess->sm, &e);
Expand Down
2 changes: 2 additions & 0 deletions src/smf/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,8 @@ typedef struct smf_sess_s {
ogs_timer_t *timer_gx_cca;
ogs_timer_t *timer_gy_cca;

bool active;

smf_ue_t *smf_ue;

bool n1_released;
Expand Down
2 changes: 1 addition & 1 deletion src/smf/gn-handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ void smf_gn_handle_update_pdp_context_request(
cause_value = OGS_GTP1_CAUSE_MANDATORY_IE_MISSING;
}

if (!sess) {
if (!sess || !sess->active) {
ogs_warn("No Context");
cause_value = OGS_GTP1_CAUSE_NON_EXISTENT;
}
Expand Down
Loading

0 comments on commit 240d821

Please sign in to comment.