[SEC] Fix Assertion ogs_gtp2_parse_uli (#3209)

This commit is contained in:
Sukchan Lee 2024-05-18 20:25:54 +09:00
parent 05deed616c
commit 5f425445a8
4 changed files with 92 additions and 49 deletions

View file

@ -629,7 +629,11 @@ int16_t ogs_gtp2_parse_uli(ogs_gtp2_uli_t *uli, ogs_tlv_octet_t *octet)
size++;
if (uli->flags.cgi) {
ogs_assert(size + sizeof(uli->cgi) <= octet->len);
if (size + sizeof(uli->cgi) > octet->len) {
ogs_error("size[%d]+sizeof(uli->cgi)[%d] > IE Length[%d]",
size, (int)sizeof(uli->cgi), octet->len);
return 0;
}
memcpy(&uli->cgi,
(unsigned char *)octet->data + size, sizeof(uli->cgi));
uli->cgi.lac = be16toh(uli->cgi.lac);
@ -637,7 +641,11 @@ int16_t ogs_gtp2_parse_uli(ogs_gtp2_uli_t *uli, ogs_tlv_octet_t *octet)
size += sizeof(uli->cgi);
}
if (uli->flags.sai) {
ogs_assert(size + sizeof(uli->sai) <= octet->len);
if (size + sizeof(uli->sai) > octet->len) {
ogs_error("size[%d]+sizeof(uli->sai)[%d] > IE Length[%d]",
size, (int)sizeof(uli->sai), octet->len);
return 0;
}
memcpy(&uli->sai,
(unsigned char *)octet->data + size, sizeof(uli->sai));
uli->sai.lac = be16toh(uli->sai.lac);
@ -645,7 +653,11 @@ int16_t ogs_gtp2_parse_uli(ogs_gtp2_uli_t *uli, ogs_tlv_octet_t *octet)
size += sizeof(uli->sai);
}
if (uli->flags.rai) {
ogs_assert(size + sizeof(uli->rai) <= octet->len);
if (size + sizeof(uli->rai) > octet->len) {
ogs_error("size[%d]+sizeof(uli->lai)[%d] > IE Length[%d]",
size, (int)sizeof(uli->lai), octet->len);
return 0;
}
memcpy(&uli->rai,
(unsigned char *)octet->data + size, sizeof(uli->rai));
uli->rai.lac = be16toh(uli->rai.lac);
@ -653,28 +665,44 @@ int16_t ogs_gtp2_parse_uli(ogs_gtp2_uli_t *uli, ogs_tlv_octet_t *octet)
size += sizeof(uli->rai);
}
if (uli->flags.tai) {
ogs_assert(size + sizeof(uli->tai) <= octet->len);
if (size + sizeof(uli->tai) > octet->len) {
ogs_error("size[%d]+sizeof(uli->tai)[%d] > IE Length[%d]",
size, (int)sizeof(uli->tai), octet->len);
return 0;
}
memcpy(&uli->tai,
(unsigned char *)octet->data + size, sizeof(uli->tai));
uli->tai.tac = be16toh(uli->tai.tac);
size += sizeof(uli->tai);
}
if (uli->flags.e_cgi) {
ogs_assert(size + sizeof(uli->e_cgi) <= octet->len);
if (size + sizeof(uli->e_cgi) > octet->len) {
ogs_error("size[%d]+sizeof(uli->e_cgi)[%d] > IE Length[%d]",
size, (int)sizeof(uli->e_cgi), octet->len);
return 0;
}
memcpy(&uli->e_cgi,
(unsigned char *)octet->data + size, sizeof(uli->e_cgi));
uli->e_cgi.cell_id = be32toh(uli->e_cgi.cell_id);
size += sizeof(uli->e_cgi);
}
if (uli->flags.lai) {
ogs_assert(size + sizeof(uli->lai) <= octet->len);
if (size + sizeof(uli->lai) > octet->len) {
ogs_error("size[%d]+sizeof(uli->lai)[%d] > IE Length[%d]",
size, (int)sizeof(uli->lai), octet->len);
return 0;
}
memcpy(&uli->lai,
(unsigned char *)octet->data + size, sizeof(uli->lai));
uli->lai.lac = be16toh(uli->lai.lac);
size += sizeof(uli->lai);
}
if (uli->flags.enodeb_id) {
ogs_assert(size + sizeof(uli->enodeb_id) <= octet->len);
if (size + sizeof(uli->enodeb_id) > octet->len) {
ogs_error("size[%d]+sizeof(uli->enodeb_id)[%d] > IE Length[%d]",
size, (int)sizeof(uli->enodeb_id), octet->len);
return 0;
}
memcpy(&uli->enodeb_id,
(unsigned char *)octet->data + size, sizeof(uli->enodeb_id));
uli->enodeb_id.enodeb_id = be16toh(uli->enodeb_id.enodeb_id);
@ -684,7 +712,8 @@ int16_t ogs_gtp2_parse_uli(ogs_gtp2_uli_t *uli, ogs_tlv_octet_t *octet)
ogs_error("Extended Macro eNodeB ID in ULI not implemented! see 3GPP TS 29.274 8.21.8");
}
ogs_assert(size == octet->len);
if (size != octet->len)
ogs_error("Mismatch IE Length[%d] != Decoded[%d]", octet->len, size);
return size;
}

View file

@ -242,21 +242,22 @@ void sgwc_s11_handle_create_session_request(
/* Set User Location Information */
if (req->user_location_information.presence == 1) {
decoded = ogs_gtp2_parse_uli(&uli, &req->user_location_information);
ogs_assert(req->user_location_information.len == decoded);
if (req->user_location_information.len == decoded) {
sgwc_ue->uli_presence = true;
sgwc_ue->uli_presence = true;
ogs_nas_to_plmn_id(&sgwc_ue->e_tai.plmn_id, &uli.tai.nas_plmn_id);
sgwc_ue->e_tai.tac = uli.tai.tac;
ogs_nas_to_plmn_id(&sgwc_ue->e_cgi.plmn_id, &uli.e_cgi.nas_plmn_id);
sgwc_ue->e_cgi.cell_id = uli.e_cgi.cell_id;
ogs_nas_to_plmn_id(&sgwc_ue->e_tai.plmn_id, &uli.tai.nas_plmn_id);
sgwc_ue->e_tai.tac = uli.tai.tac;
ogs_nas_to_plmn_id(&sgwc_ue->e_cgi.plmn_id, &uli.e_cgi.nas_plmn_id);
sgwc_ue->e_cgi.cell_id = uli.e_cgi.cell_id;
ogs_debug(" TAI[PLMN_ID:%06x,TAC:%d]",
ogs_plmn_id_hexdump(&sgwc_ue->e_tai.plmn_id),
sgwc_ue->e_tai.tac);
ogs_debug(" E_CGI[PLMN_ID:%06x,CELL_ID:0x%x]",
ogs_plmn_id_hexdump(&sgwc_ue->e_cgi.plmn_id),
sgwc_ue->e_cgi.cell_id);
ogs_debug(" TAI[PLMN_ID:%06x,TAC:%d]",
ogs_plmn_id_hexdump(&sgwc_ue->e_tai.plmn_id),
sgwc_ue->e_tai.tac);
ogs_debug(" E_CGI[PLMN_ID:%06x,CELL_ID:0x%x]",
ogs_plmn_id_hexdump(&sgwc_ue->e_cgi.plmn_id),
sgwc_ue->e_cgi.cell_id);
} else
ogs_error("Invalid User Location Info(ULI)");
}
/* Select SGW-U based on UE Location Information */
@ -542,21 +543,22 @@ void sgwc_s11_handle_modify_bearer_request(
if (req->user_location_information.presence == 1) {
decoded = ogs_gtp2_parse_uli(&uli, &req->user_location_information);
ogs_assert(req->user_location_information.len == decoded);
if (req->user_location_information.len == decoded) {
sgwc_ue->uli_presence = true;
sgwc_ue->uli_presence = true;
ogs_nas_to_plmn_id(&sgwc_ue->e_tai.plmn_id, &uli.tai.nas_plmn_id);
sgwc_ue->e_tai.tac = uli.tai.tac;
ogs_nas_to_plmn_id(&sgwc_ue->e_cgi.plmn_id, &uli.e_cgi.nas_plmn_id);
sgwc_ue->e_cgi.cell_id = uli.e_cgi.cell_id;
ogs_nas_to_plmn_id(&sgwc_ue->e_tai.plmn_id, &uli.tai.nas_plmn_id);
sgwc_ue->e_tai.tac = uli.tai.tac;
ogs_nas_to_plmn_id(&sgwc_ue->e_cgi.plmn_id, &uli.e_cgi.nas_plmn_id);
sgwc_ue->e_cgi.cell_id = uli.e_cgi.cell_id;
ogs_debug(" TAI[PLMN_ID:%06x,TAC:%d]",
ogs_plmn_id_hexdump(&sgwc_ue->e_tai.plmn_id),
sgwc_ue->e_tai.tac);
ogs_debug(" E_CGI[PLMN_ID:%06x,CELL_ID:0x%x]",
ogs_plmn_id_hexdump(&sgwc_ue->e_cgi.plmn_id),
sgwc_ue->e_cgi.cell_id);
ogs_debug(" TAI[PLMN_ID:%06x,TAC:%d]",
ogs_plmn_id_hexdump(&sgwc_ue->e_tai.plmn_id),
sgwc_ue->e_tai.tac);
ogs_debug(" E_CGI[PLMN_ID:%06x,CELL_ID:0x%x]",
ogs_plmn_id_hexdump(&sgwc_ue->e_cgi.plmn_id),
sgwc_ue->e_cgi.cell_id);
} else
ogs_error("Invalid User Location Info(ULI)");
}
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
@ -845,21 +847,22 @@ void sgwc_s11_handle_create_bearer_response(
if (rsp->user_location_information.presence == 1) {
decoded = ogs_gtp2_parse_uli(&uli, &rsp->user_location_information);
ogs_assert(rsp->user_location_information.len == decoded);
if (rsp->user_location_information.len == decoded) {
sgwc_ue->uli_presence = true;
sgwc_ue->uli_presence = true;
ogs_nas_to_plmn_id(&sgwc_ue->e_tai.plmn_id, &uli.tai.nas_plmn_id);
sgwc_ue->e_tai.tac = uli.tai.tac;
ogs_nas_to_plmn_id(&sgwc_ue->e_cgi.plmn_id, &uli.e_cgi.nas_plmn_id);
sgwc_ue->e_cgi.cell_id = uli.e_cgi.cell_id;
ogs_nas_to_plmn_id(&sgwc_ue->e_tai.plmn_id, &uli.tai.nas_plmn_id);
sgwc_ue->e_tai.tac = uli.tai.tac;
ogs_nas_to_plmn_id(&sgwc_ue->e_cgi.plmn_id, &uli.e_cgi.nas_plmn_id);
sgwc_ue->e_cgi.cell_id = uli.e_cgi.cell_id;
ogs_debug(" TAI[PLMN_ID:%06x,TAC:%d]",
ogs_plmn_id_hexdump(&sgwc_ue->e_tai.plmn_id),
sgwc_ue->e_tai.tac);
ogs_debug(" E_CGI[PLMN_ID:%06x,CELL_ID:0x%x]",
ogs_plmn_id_hexdump(&sgwc_ue->e_cgi.plmn_id),
sgwc_ue->e_cgi.cell_id);
ogs_debug(" TAI[PLMN_ID:%06x,TAC:%d]",
ogs_plmn_id_hexdump(&sgwc_ue->e_tai.plmn_id),
sgwc_ue->e_tai.tac);
ogs_debug(" E_CGI[PLMN_ID:%06x,CELL_ID:0x%x]",
ogs_plmn_id_hexdump(&sgwc_ue->e_cgi.plmn_id),
sgwc_ue->e_cgi.cell_id);
} else
ogs_error("Invalid User Location Info(ULI)");
}
ogs_assert(OGS_OK ==

View file

@ -100,7 +100,10 @@ void smf_fd_msg_avp_add_3gpp_uli(smf_sess_t *sess, struct msg *req)
/* GTPv2C and Diameter 3GPP-User-Location-Information encoding don't match */
uli_len = ogs_gtp2_parse_uli(
&uli, &sess->gtp.user_location_information);
ogs_assert(sess->gtp.user_location_information.len == uli_len);
if (sess->gtp.user_location_information.len != uli_len) {
ogs_error("Invalid User Location Information(ULI)");
return;
}
ogs_assert(sess->gtp.user_location_information.data);
ogs_assert(sess->gtp.user_location_information.len);

View file

@ -207,7 +207,15 @@ uint8_t smf_s5c_handle_create_session_request(
if (sess->gtp_rat_type == OGS_GTP2_RAT_TYPE_EUTRAN) {
/* User Location Inforation is mandatory only for E-UTRAN */
ogs_assert(req->user_location_information.presence);
ogs_gtp2_parse_uli(&uli, &req->user_location_information);
if (req->user_location_information.presence == 0) {
ogs_error("No User Location Information(ULI)");
return OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
}
decoded = ogs_gtp2_parse_uli(&uli, &req->user_location_information);
if (req->user_location_information.len != decoded) {
ogs_error("Invalid User Location Information(ULI)");
return OGS_GTP2_CAUSE_MANDATORY_IE_INCORRECT;
}
memcpy(&sess->e_tai, &uli.tai, sizeof(sess->e_tai));
memcpy(&sess->e_cgi, &uli.e_cgi, sizeof(sess->e_cgi));