fix byte buffer double free in EPC

master
Francisco 4 years ago committed by Francisco Paisana
parent d2ddcb0d4e
commit 798f1e57e6

@ -196,6 +196,7 @@ public:
print_error("Error deallocating PDU: Addr=0x%p, name=%s not found in pool", (void*)b, b->debug_name);
#else
print_error("Error deallocating PDU: Addr=0x%p", (void*)b);
srslog::fetch_basic_logger("EPC").error("ERROR deallocating PDU: Addr=0x%p\n", (void*)b);
#endif
}
}

@ -107,15 +107,15 @@ public:
virtual bool modify_gtpu_tunnel(in_addr_t ue_ipv4, srslte::gtpc_f_teid_ie dw_user_fteid, uint32_t up_ctrl_teid) = 0;
virtual bool delete_gtpu_tunnel(in_addr_t ue_ipv4) = 0;
virtual bool delete_gtpc_tunnel(in_addr_t ue_ipv4) = 0;
virtual void send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid,
std::queue<srslte::byte_buffer_t*>& pkt_queue) = 0;
virtual void send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid,
std::queue<srslte::unique_byte_buffer_t>& pkt_queue) = 0;
};
class gtpc_interface_gtpu // GTP-U -> GTP-C
{
public:
virtual bool queue_downlink_packet(uint32_t spgw_ctr_teid, srslte::byte_buffer_t* msg) = 0;
virtual bool send_downlink_data_notification(uint32_t spgw_ctr_teid) = 0;
virtual bool queue_downlink_packet(uint32_t spgw_ctr_teid, srslte::unique_byte_buffer_t msg) = 0;
virtual bool send_downlink_data_notification(uint32_t spgw_ctr_teid) = 0;
};
} // namespace srsepc

@ -55,8 +55,8 @@ public:
const srslte::gtpc_header& header,
const srslte::gtpc_downlink_data_notification_failure_indication& not_fail);
virtual bool queue_downlink_packet(uint32_t spgw_ctr_teid, srslte::byte_buffer_t* msg);
virtual bool send_downlink_data_notification(uint32_t spgw_ctr_teid);
virtual bool queue_downlink_packet(uint32_t spgw_ctr_teid, srslte::unique_byte_buffer_t msg) override;
virtual bool send_downlink_data_notification(uint32_t spgw_ctr_teid) override;
spgw_tunnel_ctx_t* create_gtpc_ctx(const srslte::gtpc_create_session_request& cs_req);
bool delete_gtpc_ctx(uint32_t ctrl_teid);

@ -37,7 +37,7 @@ public:
int get_sgi();
int get_s1u();
void handle_sgi_pdu(srslte::byte_buffer_t* msg);
void handle_sgi_pdu(srslte::unique_byte_buffer_t msg);
void handle_s1u_pdu(srslte::byte_buffer_t* msg);
void send_s1u_pdu(srslte::gtp_fteid_t enb_fteid, srslte::byte_buffer_t* msg);
@ -46,8 +46,8 @@ public:
virtual bool modify_gtpu_tunnel(in_addr_t ue_ipv4, srslte::gtp_fteid_t dw_user_fteid, uint32_t up_ctr_fteid);
virtual bool delete_gtpu_tunnel(in_addr_t ue_ipv4);
virtual bool delete_gtpc_tunnel(in_addr_t ue_ipv4);
virtual void send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid,
std::queue<srslte::byte_buffer_t*>& pkt_queue);
virtual void send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid,
std::queue<srslte::unique_byte_buffer_t>& pkt_queue);
spgw* m_spgw;
gtpc_interface_gtpu* m_gtpc;

@ -42,15 +42,15 @@ typedef struct {
} spgw_args_t;
typedef struct spgw_tunnel_ctx {
uint64_t imsi;
in_addr_t ue_ipv4;
uint8_t ebi;
srslte::gtp_fteid_t up_ctrl_fteid;
srslte::gtp_fteid_t up_user_fteid;
srslte::gtp_fteid_t dw_ctrl_fteid;
srslte::gtp_fteid_t dw_user_fteid;
bool paging_pending;
std::queue<srslte::byte_buffer_t*> paging_queue;
uint64_t imsi;
in_addr_t ue_ipv4;
uint8_t ebi;
srslte::gtp_fteid_t up_ctrl_fteid;
srslte::gtp_fteid_t up_user_fteid;
srslte::gtp_fteid_t dw_ctrl_fteid;
srslte::gtp_fteid_t dw_user_fteid;
bool paging_pending;
std::queue<srslte::unique_byte_buffer_t> paging_queue;
} spgw_tunnel_ctx_t;
class spgw : public srslte::thread

@ -229,9 +229,8 @@ int mbms_gw::init_m1_u(mbms_gw_args_t* args)
void mbms_gw::run_thread()
{
// Mark the thread as running
m_running = true;
srslte::byte_buffer_t* msg;
msg = new srslte::byte_buffer_t();
m_running = true;
srslte::unique_byte_buffer_t msg = srslte::make_byte_buffer();
uint8_t seq = 0;
while (m_running) {
@ -245,10 +244,9 @@ void mbms_gw::run_thread()
m_logger.error("Error reading from TUN interface. Error: %s", strerror(errno));
} else {
msg->N_bytes = n;
handle_sgi_md_pdu(msg);
handle_sgi_md_pdu(msg.get());
}
}
delete msg;
return;
}

@ -196,9 +196,9 @@ bool nas::handle_imsi_attach_request_unknown_ue(uint32_t
const nas_init_t& args,
const nas_if_t& itf)
{
nas* nas_ctx;
srslte::byte_buffer_t* nas_tx;
auto& nas_logger = srslog::fetch_basic_logger("NAS");
nas* nas_ctx;
srslte::unique_byte_buffer_t nas_tx;
auto& nas_logger = srslog::fetch_basic_logger("NAS");
// Interfaces
s1ap_interface_nas* s1ap = itf.s1ap;
@ -260,7 +260,6 @@ bool nas::handle_imsi_attach_request_unknown_ue(uint32_t
nas_ctx->m_sec_ctx.xres)) {
srslte::console("User not found. IMSI %015" PRIu64 "\n", nas_ctx->m_emm_ctx.imsi);
nas_logger.info("User not found. IMSI %015" PRIu64 "", nas_ctx->m_emm_ctx.imsi);
delete nas_ctx;
return false;
}
@ -274,13 +273,12 @@ bool nas::handle_imsi_attach_request_unknown_ue(uint32_t
s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id);
// Pack NAS Authentication Request in Downlink NAS Transport msg
nas_tx = new srslte::byte_buffer_t();
nas_ctx->pack_authentication_request(nas_tx);
nas_tx = srslte::make_byte_buffer();
nas_ctx->pack_authentication_request(nas_tx.get());
// Send reply to eNB
s1ap->send_downlink_nas_transport(
nas_ctx->m_ecm_ctx.enb_ue_s1ap_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id, nas_tx, nas_ctx->m_ecm_ctx.enb_sri);
delete nas_tx;
nas_ctx->m_ecm_ctx.enb_ue_s1ap_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), nas_ctx->m_ecm_ctx.enb_sri);
nas_logger.info("Downlink NAS: Sending Authentication Request");
srslte::console("Downlink NAS: Sending Authentication Request\n");
@ -327,8 +325,8 @@ bool nas::handle_guti_attach_request_unknown_ue(uint32_t
const nas_if_t& itf)
{
nas* nas_ctx;
srslte::byte_buffer_t* nas_tx;
nas* nas_ctx;
srslte::unique_byte_buffer_t nas_tx;
// Interfaces
s1ap_interface_nas* s1ap = itf.s1ap;
@ -384,11 +382,10 @@ bool nas::handle_guti_attach_request_unknown_ue(uint32_t
s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id);
// Send Identity Request
nas_tx = new srslte::byte_buffer_t();
nas_ctx->pack_identity_request(nas_tx);
nas_tx = srslte::make_byte_buffer();
nas_ctx->pack_identity_request(nas_tx.get());
s1ap->send_downlink_nas_transport(
nas_ctx->m_ecm_ctx.enb_ue_s1ap_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id, nas_tx, nas_ctx->m_ecm_ctx.enb_sri);
delete nas_tx;
nas_ctx->m_ecm_ctx.enb_ue_s1ap_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), nas_ctx->m_ecm_ctx.enb_sri);
return true;
}
@ -402,9 +399,9 @@ bool nas::handle_guti_attach_request_known_ue(nas*
const nas_init_t& args,
const nas_if_t& itf)
{
bool msg_valid = false;
srslte::byte_buffer_t* nas_tx;
auto& nas_logger = srslog::fetch_basic_logger("NAS");
bool msg_valid = false;
srslte::unique_byte_buffer_t nas_tx;
auto& nas_logger = srslog::fetch_basic_logger("NAS");
emm_ctx_t* emm_ctx = &nas_ctx->m_emm_ctx;
ecm_ctx_t* ecm_ctx = &nas_ctx->m_ecm_ctx;
@ -461,12 +458,12 @@ bool nas::handle_guti_attach_request_known_ue(nas*
nas_logger.info(sec_ctx->k_enb, 32, "Key eNodeB (k_enb)");
// Send reply
nas_tx = new srslte::byte_buffer_t();
nas_tx = srslte::make_byte_buffer();
if (ecm_ctx->eit) {
srslte::console("Secure ESM information transfer requested.\n");
nas_logger.info("Secure ESM information transfer requested.");
nas_ctx->pack_esm_information_request(nas_tx);
s1ap->send_downlink_nas_transport(ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, nas_tx, *enb_sri);
nas_ctx->pack_esm_information_request(nas_tx.get());
s1ap->send_downlink_nas_transport(ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, nas_tx.get(), *enb_sri);
} else {
// Get subscriber info from HSS
uint8_t default_bearer = 5;
@ -476,7 +473,6 @@ bool nas::handle_guti_attach_request_known_ue(nas*
gtpc->send_create_session_request(emm_ctx->imsi);
}
sec_ctx->ul_nas_count++;
delete nas_tx;
return true;
} else {
if (emm_ctx->state != EMM_STATE_DEREGISTERED) {
@ -535,12 +531,11 @@ bool nas::handle_guti_attach_request_known_ue(nas*
// Restarting security context. Reseting eKSI to 0.
sec_ctx->eksi = 0;
nas_tx = new srslte::byte_buffer_t();
nas_ctx->pack_authentication_request(nas_tx);
nas_tx = srslte::unique_byte_buffer_t();
nas_ctx->pack_authentication_request(nas_tx.get());
// Send reply to eNB
s1ap->send_downlink_nas_transport(ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, nas_tx, *enb_sri);
delete nas_tx;
s1ap->send_downlink_nas_transport(ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, nas_tx.get(), *enb_sri);
nas_logger.info("Downlink NAS: Sent Authentication Request");
srslte::console("Downlink NAS: Sent Authentication Request\n");
return true;
@ -585,10 +580,9 @@ bool nas::handle_service_request(uint32_t m_tmsi,
nas_tmp.m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id;
nas_tmp.m_ecm_ctx.mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id();
srslte::byte_buffer_t* nas_tx = new srslte::byte_buffer_t();
nas_tmp.pack_service_reject(nas_tx, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED);
s1ap->send_downlink_nas_transport(enb_ue_s1ap_id, nas_tmp.m_ecm_ctx.mme_ue_s1ap_id, nas_tx, *enb_sri);
delete nas_tx;
srslte::unique_byte_buffer_t nas_tx = srslte::make_byte_buffer();
nas_tmp.pack_service_reject(nas_tx.get(), LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED);
s1ap->send_downlink_nas_transport(enb_ue_s1ap_id, nas_tmp.m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), *enb_sri);
return true;
}
@ -600,10 +594,9 @@ bool nas::handle_service_request(uint32_t m_tmsi,
nas_tmp.m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id;
nas_tmp.m_ecm_ctx.mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id();
srslte::byte_buffer_t* nas_tx = new srslte::byte_buffer_t();
nas_tmp.pack_service_reject(nas_tx, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED);
s1ap->send_downlink_nas_transport(enb_ue_s1ap_id, nas_tmp.m_ecm_ctx.mme_ue_s1ap_id, nas_tx, *enb_sri);
delete nas_tx;
srslte::unique_byte_buffer_t nas_tx = srslte::make_byte_buffer();
nas_tmp.pack_service_reject(nas_tx.get(), LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED);
s1ap->send_downlink_nas_transport(enb_ue_s1ap_id, nas_tmp.m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), *enb_sri);
return true;
}
emm_ctx_t* emm_ctx = &nas_ctx->m_emm_ctx;
@ -685,10 +678,9 @@ bool nas::handle_service_request(uint32_t m_tmsi,
ecm_ctx->mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id();
s1ap->add_nas_ctx_to_mme_ue_s1ap_id_map(nas_ctx);
s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id);
srslte::byte_buffer_t* nas_tx = new srslte::byte_buffer_t();
nas_ctx->pack_service_reject(nas_tx, LIBLTE_MME_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
s1ap->send_downlink_nas_transport(ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, nas_tx, *enb_sri);
delete nas_tx;
srslte::unique_byte_buffer_t nas_tx = srslte::make_byte_buffer();
nas_ctx->pack_service_reject(nas_tx.get(), LIBLTE_MME_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
s1ap->send_downlink_nas_transport(ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, nas_tx.get(), *enb_sri);
srslte::console("Service Request -- Short MAC invalid. Sending service reject.\n");
nas_logger.warning("Service Request -- Short MAC invalid. Sending service reject.");
@ -790,10 +782,9 @@ bool nas::handle_tracking_area_update_request(uint32_t m_tmsi,
nas_tmp.m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id;
nas_tmp.m_ecm_ctx.mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id();
srslte::byte_buffer_t* nas_tx = new srslte::byte_buffer_t();
nas_tmp.pack_tracking_area_update_reject(nas_tx, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED);
s1ap->send_downlink_nas_transport(enb_ue_s1ap_id, nas_tmp.m_ecm_ctx.mme_ue_s1ap_id, nas_tx, *enb_sri);
delete nas_tx;
srslte::unique_byte_buffer_t nas_tx = srslte::make_byte_buffer();
nas_tmp.pack_tracking_area_update_reject(nas_tx.get(), LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED);
s1ap->send_downlink_nas_transport(enb_ue_s1ap_id, nas_tmp.m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), *enb_sri);
return true;
}
@ -894,12 +885,12 @@ bool nas::handle_attach_request(srslte::byte_buffer_t* nas_rx)
m_s1ap->add_nas_ctx_to_imsi_map(this);
// Pack NAS Authentication Request in Downlink NAS Transport msg
srslte::byte_buffer_t* nas_tx = new srslte::byte_buffer_t();
pack_authentication_request(nas_tx);
srslte::unique_byte_buffer_t nas_tx = srslte::make_byte_buffer();
pack_authentication_request(nas_tx.get());
// Send reply to eNB
m_s1ap->send_downlink_nas_transport(m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri);
delete nas_tx;
m_s1ap->send_downlink_nas_transport(
m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri);
m_logger.info("Downlink NAS: Sending Authentication Request");
srslte::console("Downlink NAS: Sending Authentication Request\n");
@ -912,7 +903,7 @@ bool nas::handle_attach_request(srslte::byte_buffer_t* nas_rx)
bool nas::handle_authentication_response(srslte::byte_buffer_t* nas_rx)
{
srslte::byte_buffer_t* nas_tx;
srslte::unique_byte_buffer_t nas_tx;
LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT auth_resp;
bool ue_valid = true;
@ -936,14 +927,14 @@ bool nas::handle_authentication_response(srslte::byte_buffer_t* nas_rx)
}
}
nas_tx = new srslte::byte_buffer_t();
nas_tx = srslte::make_byte_buffer();
if (!ue_valid) {
// Authentication rejected
srslte::console("UE Authentication Rejected.\n");
m_logger.warning("UE Authentication Rejected.");
// Send back Athentication Reject
pack_authentication_reject(nas_tx);
pack_authentication_reject(nas_tx.get());
m_logger.info("Downlink NAS: Sending Authentication Reject.");
} else {
// Authentication accepted
@ -952,19 +943,19 @@ bool nas::handle_authentication_response(srslte::byte_buffer_t* nas_rx)
// Send Security Mode Command
m_sec_ctx.ul_nas_count = 0; // Reset the NAS uplink counter for the right key k_enb derivation
pack_security_mode_command(nas_tx);
pack_security_mode_command(nas_tx.get());
srslte::console("Downlink NAS: Sending NAS Security Mode Command.\n");
}
// Send reply
m_s1ap->send_downlink_nas_transport(m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri);
delete nas_tx;
m_s1ap->send_downlink_nas_transport(
m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri);
return true;
}
bool nas::handle_security_mode_complete(srslte::byte_buffer_t* nas_rx)
{
srslte::byte_buffer_t* nas_tx;
srslte::unique_byte_buffer_t nas_tx;
LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sm_comp;
// Get NAS security mode complete
@ -979,15 +970,16 @@ bool nas::handle_security_mode_complete(srslte::byte_buffer_t* nas_rx)
srslte::console("Security Mode Command Complete -- IMSI: %015" PRIu64 "\n", m_emm_ctx.imsi);
// Check wether secure ESM information transfer is required
nas_tx = new srslte::byte_buffer_t();
nas_tx = srslte::make_byte_buffer();
if (m_ecm_ctx.eit == true) {
// Secure ESM information transfer is required
srslte::console("Sending ESM information request\n");
m_logger.info("Sending ESM information request");
// Packing ESM information request
pack_esm_information_request(nas_tx);
m_s1ap->send_downlink_nas_transport(m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri);
pack_esm_information_request(nas_tx.get());
m_s1ap->send_downlink_nas_transport(
m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri);
} else {
// Secure ESM information transfer not necessary
// Sending create session request to SP-GW.
@ -997,7 +989,6 @@ bool nas::handle_security_mode_complete(srslte::byte_buffer_t* nas_rx)
srslte::console("Getting subscription information -- QCI %d\n", m_esm_ctx[default_bearer].qci);
m_gtpc->send_create_session_request(m_emm_ctx.imsi);
}
delete nas_tx;
return true;
}
@ -1006,7 +997,7 @@ bool nas::handle_attach_complete(srslte::byte_buffer_t* nas_rx)
LIBLTE_MME_ATTACH_COMPLETE_MSG_STRUCT attach_comp;
uint8_t pd, msg_type;
LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT act_bearer;
srslte::byte_buffer_t* nas_tx;
srslte::unique_byte_buffer_t nas_tx;
// Get NAS authentication response
std::memset(&attach_comp, 0, sizeof(attach_comp));
@ -1036,11 +1027,11 @@ bool nas::handle_attach_complete(srslte::byte_buffer_t* nas_rx)
m_emm_ctx.imsi, act_bearer.eps_bearer_id, &m_esm_ctx[act_bearer.eps_bearer_id].enb_fteid);
// Send reply to EMM Info to UE
nas_tx = new srslte::byte_buffer_t();
pack_emm_information(nas_tx);
nas_tx = srslte::make_byte_buffer();
pack_emm_information(nas_tx.get());
m_s1ap->send_downlink_nas_transport(m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri);
delete nas_tx;
m_s1ap->send_downlink_nas_transport(
m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri);
srslte::console("Sending EMM Information\n");
m_logger.info("Sending EMM Information");
@ -1085,7 +1076,7 @@ bool nas::handle_esm_information_response(srslte::byte_buffer_t* nas_rx)
bool nas::handle_identity_response(srslte::byte_buffer_t* nas_rx)
{
srslte::byte_buffer_t* nas_tx;
srslte::unique_byte_buffer_t nas_tx;
LIBLTE_MME_ID_RESPONSE_MSG_STRUCT id_resp;
LIBLTE_ERROR_ENUM err = liblte_mme_unpack_identity_response_msg((LIBLTE_BYTE_MSG_STRUCT*)nas_rx, &id_resp);
@ -1125,12 +1116,12 @@ bool nas::handle_identity_response(srslte::byte_buffer_t* nas_rx)
m_s1ap->add_nas_ctx_to_imsi_map(this);
// Pack NAS Authentication Request in Downlink NAS Transport msg
nas_tx = new srslte::byte_buffer_t();
pack_authentication_request(nas_tx);
nas_tx = srslte::make_byte_buffer();
pack_authentication_request(nas_tx.get());
// Send reply to eNB
m_s1ap->send_downlink_nas_transport(m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri);
delete nas_tx;
m_s1ap->send_downlink_nas_transport(
m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri);
m_logger.info("Downlink NAS: Sent Authentication Request");
srslte::console("Downlink NAS: Sent Authentication Request\n");
@ -1142,16 +1133,16 @@ bool nas::handle_tracking_area_update_request(srslte::byte_buffer_t* nas_rx)
srslte::console("Warning: Tracking Area Update Request messages not handled yet.\n");
m_logger.warning("Warning: Tracking Area Update Request messages not handled yet.");
srslte::byte_buffer_t* nas_tx;
srslte::unique_byte_buffer_t nas_tx;
/* TAU handling unsupported, therefore send TAU reject with cause IMPLICITLY DETACHED.
* this will trigger full re-attach by the UE, instead of going to a TAU request loop */
nas_tx = new srslte::byte_buffer_t();
nas_tx = srslte::make_byte_buffer();
// TODO we could enable integrity protection in some cases, but UE should comply anyway
pack_tracking_area_update_reject(nas_tx, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED);
pack_tracking_area_update_reject(nas_tx.get(), LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED);
// Send reply
m_s1ap->send_downlink_nas_transport(m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri);
delete nas_tx;
m_s1ap->send_downlink_nas_transport(
m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri);
return true;
}
@ -1160,7 +1151,7 @@ bool nas::handle_authentication_failure(srslte::byte_buffer_t* nas_rx)
{
m_logger.info("Received Authentication Failure");
srslte::byte_buffer_t* nas_tx;
srslte::unique_byte_buffer_t nas_tx;
LIBLTE_MME_AUTHENTICATION_FAILURE_MSG_STRUCT auth_fail;
LIBLTE_ERROR_ENUM err;
@ -1203,13 +1194,12 @@ bool nas::handle_authentication_failure(srslte::byte_buffer_t* nas_rx)
m_sec_ctx.eksi = (m_sec_ctx.eksi + 1) % 6;
// Pack NAS Authentication Request in Downlink NAS Transport msg
nas_tx = new srslte::byte_buffer_t();
pack_authentication_request(nas_tx);
nas_tx = srslte::make_byte_buffer();
pack_authentication_request(nas_tx.get());
// Send reply to eNB
m_s1ap->send_downlink_nas_transport(
m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri);
delete nas_tx;
m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri);
m_logger.info("Downlink NAS: Sent Authentication Request");
srslte::console("Downlink NAS: Sent Authentication Request\n");

@ -80,16 +80,16 @@ void s1ap_nas_transport::init()
bool s1ap_nas_transport::handle_initial_ue_message(const asn1::s1ap::init_ue_msg_s& init_ue,
struct sctp_sndrcvinfo* enb_sri)
{
bool err, mac_valid;
uint8_t pd, msg_type, sec_hdr_type;
srslte::byte_buffer_t* nas_msg = new srslte::byte_buffer_t();
bool err, mac_valid;
uint8_t pd, msg_type, sec_hdr_type;
srslte::unique_byte_buffer_t nas_msg = srslte::make_byte_buffer();
memcpy(nas_msg->msg, init_ue.protocol_ies.nas_pdu.value.data(), init_ue.protocol_ies.nas_pdu.value.size());
nas_msg->N_bytes = init_ue.protocol_ies.nas_pdu.value.size();
uint64_t imsi = 0;
uint32_t m_tmsi = 0;
uint32_t enb_ue_s1ap_id = init_ue.protocol_ies.enb_ue_s1ap_id.value.value;
liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg, &pd, &msg_type);
liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg.get(), &pd, &msg_type);
srslte::console("Initial UE message: %s\n", liblte_nas_msg_type_to_string(msg_type));
m_logger.info("Initial UE message: %s", liblte_nas_msg_type_to_string(msg_type));
@ -102,29 +102,29 @@ bool s1ap_nas_transport::handle_initial_ue_message(const asn1::s1ap::init_ue_msg
case LIBLTE_MME_MSG_TYPE_ATTACH_REQUEST:
srslte::console("Received Initial UE message -- Attach Request\n");
m_logger.info("Received Initial UE message -- Attach Request");
err = nas::handle_attach_request(enb_ue_s1ap_id, enb_sri, nas_msg, m_nas_init, m_nas_if);
err = nas::handle_attach_request(enb_ue_s1ap_id, enb_sri, nas_msg.get(), m_nas_init, m_nas_if);
break;
case LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST:
srslte::console("Received Initial UE message -- Service Request\n");
m_logger.info("Received Initial UE message -- Service Request");
err = nas::handle_service_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg, m_nas_init, m_nas_if);
err = nas::handle_service_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg.get(), m_nas_init, m_nas_if);
break;
case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST:
srslte::console("Received Initial UE message -- Detach Request\n");
m_logger.info("Received Initial UE message -- Detach Request");
err = nas::handle_detach_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg, m_nas_init, m_nas_if);
err = nas::handle_detach_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg.get(), m_nas_init, m_nas_if);
break;
case LIBLTE_MME_MSG_TYPE_TRACKING_AREA_UPDATE_REQUEST:
srslte::console("Received Initial UE message -- Tracking Area Update Request\n");
m_logger.info("Received Initial UE message -- Tracking Area Update Request");
err = nas::handle_tracking_area_update_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg, m_nas_init, m_nas_if);
err = nas::handle_tracking_area_update_request(
m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg.get(), m_nas_init, m_nas_if);
break;
default:
m_logger.info("Unhandled Initial UE Message 0x%x ", msg_type);
srslte::console("Unhandled Initial UE Message 0x%x \n", msg_type);
err = false;
}
delete nas_msg;
return err;
}
@ -150,13 +150,13 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
sec_ctx_t* sec_ctx = &nas_ctx->m_sec_ctx;
// Parse NAS message header
srslte::byte_buffer_t* nas_msg = new srslte::byte_buffer_t();
srslte::unique_byte_buffer_t nas_msg = srslte::make_byte_buffer();
memcpy(nas_msg->msg, ul_xport.protocol_ies.nas_pdu.value.data(), ul_xport.protocol_ies.nas_pdu.value.size());
nas_msg->N_bytes = ul_xport.protocol_ies.nas_pdu.value.size();
bool msg_encrypted = false;
// Parse the message security header
liblte_mme_parse_msg_sec_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg, &pd, &sec_hdr_type);
liblte_mme_parse_msg_sec_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg.get(), &pd, &sec_hdr_type);
// Invalid Security Header Type simply return function
if (!(sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS ||
@ -165,7 +165,6 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_WITH_NEW_EPS_SECURITY_CONTEXT ||
sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT)) {
m_logger.error("Unhandled security header type in Uplink NAS Transport: %d", sec_hdr_type);
delete nas_msg;
return false;
}
// Todo: Check on count mismatch of uplink count and do resync nas counter...
@ -175,7 +174,7 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED ||
sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_WITH_NEW_EPS_SECURITY_CONTEXT ||
sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT) {
mac_valid = nas_ctx->integrity_check(nas_msg);
mac_valid = nas_ctx->integrity_check(nas_msg.get());
if (mac_valid == false) {
m_logger.warning("Invalid MAC message. Even if security header indicates integrity protection (Maybe: "
"Identity Response or Authentication Response)");
@ -186,13 +185,13 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED ||
sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT) {
m_logger.debug(nas_msg->msg, nas_msg->N_bytes, "Encrypted");
nas_ctx->cipher_decrypt(nas_msg);
nas_ctx->cipher_decrypt(nas_msg.get());
msg_encrypted = true;
m_logger.debug(nas_msg->msg, nas_msg->N_bytes, "Decrypted");
}
// Now parse message header and handle message
liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg, &pd, &msg_type);
liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg.get(), &pd, &msg_type);
// Find UE EMM context if message is security protected.
if (sec_hdr_type != LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS) {
@ -205,7 +204,6 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
m_logger.warning(
"Uplink NAS: could not find security context for integrity protected message. MME-UE S1AP id: %d",
mme_ue_s1ap_id);
delete nas_msg;
return false;
}
}
@ -231,17 +229,17 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
case LIBLTE_MME_MSG_TYPE_ATTACH_REQUEST:
m_logger.info("UL NAS: Attach Request");
srslte::console("UL NAS: Attach Resquest\n");
nas_ctx->handle_attach_request(nas_msg);
nas_ctx->handle_attach_request(nas_msg.get());
break;
case LIBLTE_MME_MSG_TYPE_IDENTITY_RESPONSE:
m_logger.info("UL NAS: Received Identity Response");
srslte::console("UL NAS: Received Identity Response\n");
nas_ctx->handle_identity_response(nas_msg);
nas_ctx->handle_identity_response(nas_msg.get());
break;
case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_RESPONSE:
m_logger.info("UL NAS: Received Authentication Response");
srslte::console("UL NAS: Received Authentication Response\n");
nas_ctx->handle_authentication_response(nas_msg);
nas_ctx->handle_authentication_response(nas_msg.get());
// In case of a successful authentication response, security mode command follows.
// Reset counter for incoming security mode complete
sec_ctx->ul_nas_count = 0;
@ -252,21 +250,21 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_FAILURE:
m_logger.info("UL NAS: Authentication Failure");
srslte::console("UL NAS: Authentication Failure\n");
nas_ctx->handle_authentication_failure(nas_msg);
nas_ctx->handle_authentication_failure(nas_msg.get());
break;
// Detach request can be sent not integrity protected when "power off" option is used
case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST:
m_logger.info("UL NAS: Detach Request");
srslte::console("UL NAS: Detach Request\n");
// TODO: check integrity protection in detach request
nas_ctx->handle_detach_request(nas_msg);
nas_ctx->handle_detach_request(nas_msg.get());
break;
case LIBLTE_MME_MSG_TYPE_SECURITY_MODE_COMPLETE:
m_logger.info("UL NAS: Received Security Mode Complete");
srslte::console("UL NAS: Received Security Mode Complete\n");
if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT &&
mac_valid == true) {
nas_ctx->handle_security_mode_complete(nas_msg);
nas_ctx->handle_security_mode_complete(nas_msg.get());
} else {
// Security Mode Complete was not integrity protected
srslte::console("Security Mode Complete %s. Discard message.\n",
@ -280,7 +278,7 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
m_logger.info("UL NAS: Received Attach Complete");
srslte::console("UL NAS: Received Attach Complete\n");
if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED && mac_valid == true) {
nas_ctx->handle_attach_complete(nas_msg);
nas_ctx->handle_attach_complete(nas_msg.get());
} else {
// Attach Complete was not integrity protected
srslte::console("Attach Complete not integrity protected. Discard message.\n");
@ -292,7 +290,7 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
m_logger.info("UL NAS: Received ESM Information Response");
srslte::console("UL NAS: Received ESM Information Response\n");
if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED && mac_valid == true) {
nas_ctx->handle_esm_information_response(nas_msg);
nas_ctx->handle_esm_information_response(nas_msg.get());
} else {
// Attach Complete was not integrity protected
srslte::console("ESM Information Response %s. Discard message.\n",
@ -305,12 +303,11 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
case LIBLTE_MME_MSG_TYPE_TRACKING_AREA_UPDATE_REQUEST:
m_logger.info("UL NAS: Tracking Area Update Request");
srslte::console("UL NAS: Tracking Area Update Request\n");
nas_ctx->handle_tracking_area_update_request(nas_msg);
nas_ctx->handle_tracking_area_update_request(nas_msg.get());
break;
default:
m_logger.warning("Unhandled NAS integrity protected message %s", liblte_nas_msg_type_to_string(msg_type));
srslte::console("Unhandled NAS integrity protected message %s\n", liblte_nas_msg_type_to_string(msg_type));
delete nas_msg;
return false;
}
@ -319,7 +316,6 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr
if (increase_ul_nas_cnt == true) {
sec_ctx->ul_nas_count++;
}
delete nas_msg;
return true;
}

@ -484,7 +484,7 @@ bool spgw::gtpc::delete_gtpc_ctx(uint32_t ctrl_teid)
/*
* Queueing functions
*/
bool spgw::gtpc::queue_downlink_packet(uint32_t ctrl_teid, srslte::byte_buffer_t* msg)
bool spgw::gtpc::queue_downlink_packet(uint32_t ctrl_teid, srslte::unique_byte_buffer_t msg)
{
spgw_tunnel_ctx_t* tunnel_ctx;
if (!m_teid_to_tunnel_ctx.count(ctrl_teid)) {
@ -498,7 +498,7 @@ bool spgw::gtpc::queue_downlink_packet(uint32_t ctrl_teid, srslte::byte_buffer_t
}
if (tunnel_ctx->paging_queue.size() < m_max_paging_queue) {
tunnel_ctx->paging_queue.push(msg);
tunnel_ctx->paging_queue.push(std::move(msg));
m_logger.debug(
"Queued packet. IMSI %" PRIu64 ", Packets in Queue %zd", tunnel_ctx->imsi, tunnel_ctx->paging_queue.size());
} else {
@ -509,7 +509,6 @@ bool spgw::gtpc::queue_downlink_packet(uint32_t ctrl_teid, srslte::byte_buffer_t
return true;
pkt_discard:
delete msg;
return false;
}
@ -520,9 +519,8 @@ bool spgw::gtpc::free_all_queued_packets(spgw_tunnel_ctx_t* tunnel_ctx)
}
while (!tunnel_ctx->paging_queue.empty()) {
srslte::byte_buffer_t* pkt = tunnel_ctx->paging_queue.front();
srslte::unique_byte_buffer_t pkt = std::move(tunnel_ctx->paging_queue.front());
m_logger.debug("Dropping packet. Bytes %d", pkt->N_bytes);
delete pkt;
tunnel_ctx->paging_queue.pop();
}
return true;

@ -186,7 +186,7 @@ int spgw::gtpu::init_s1u(spgw_args_t* args)
return SRSLTE_SUCCESS;
}
void spgw::gtpu::handle_sgi_pdu(srslte::byte_buffer_t* msg)
void spgw::gtpu::handle_sgi_pdu(srslte::unique_byte_buffer_t msg)
{
bool usr_found = false;
bool ctr_found = false;
@ -227,24 +227,17 @@ void spgw::gtpu::handle_sgi_pdu(srslte::byte_buffer_t* msg)
// Handle SGi packet
if (usr_found == false && ctr_found == false) {
m_logger.debug("Packet for unknown UE.");
goto pkt_discard_out;
} else if (usr_found == false && ctr_found == true) {
m_logger.debug("Packet for attached UE that is not ECM connected.");
m_logger.debug("Triggering Donwlink Notification Requset.");
m_gtpc->send_downlink_data_notification(spgw_teid);
m_gtpc->queue_downlink_packet(spgw_teid, msg);
m_gtpc->queue_downlink_packet(spgw_teid, std::move(msg));
return;
} else if (usr_found == false && ctr_found == true) {
m_logger.error("User plane tunnel found without a control plane tunnel present.");
goto pkt_discard_out;
} else {
send_s1u_pdu(enb_fteid, msg);
send_s1u_pdu(enb_fteid, msg.get());
}
return;
pkt_discard_out:
delete msg;
return;
}
void spgw::gtpu::handle_s1u_pdu(srslte::byte_buffer_t* msg)
@ -298,17 +291,16 @@ void spgw::gtpu::send_s1u_pdu(srslte::gtp_fteid_t enb_fteid, srslte::byte_buffer
out:
m_logger.debug("Deallocating packet after sending S1-U message");
delete msg;
return;
}
void spgw::gtpu::send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid,
std::queue<srslte::byte_buffer_t*>& pkt_queue)
void spgw::gtpu::send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid,
std::queue<srslte::unique_byte_buffer_t>& pkt_queue)
{
m_logger.debug("Sending all queued packets");
while (!pkt_queue.empty()) {
srslte::byte_buffer_t* msg = pkt_queue.front();
send_s1u_pdu(dw_user_fteid, msg);
srslte::unique_byte_buffer_t msg = std::move(pkt_queue.front());
send_s1u_pdu(dw_user_fteid, msg.get());
pkt_queue.pop();
}
return;

@ -136,7 +136,7 @@ void spgw::run_thread()
m_logger.debug("Message received at SPGW: SGi Message");
sgi_msg = srslte::make_byte_buffer("spgw::run_thread::sgi_msg");
sgi_msg->N_bytes = read(sgi, sgi_msg->msg, buf_len);
m_gtpu->handle_sgi_pdu(sgi_msg.get());
m_gtpu->handle_sgi_pdu(std::move(sgi_msg));
}
if (FD_ISSET(s1u, &set)) {
m_logger.debug("Message received at SPGW: S1-U Message");

Loading…
Cancel
Save