From 798f1e57e61e2252b532981ac5311a5db4a57c17 Mon Sep 17 00:00:00 2001 From: Francisco Date: Sun, 7 Feb 2021 21:30:31 +0000 Subject: [PATCH] fix byte buffer double free in EPC --- lib/include/srslte/common/buffer_pool.h | 1 + .../srslte/interfaces/epc_interfaces.h | 8 +- srsepc/hdr/spgw/gtpc.h | 4 +- srsepc/hdr/spgw/gtpu.h | 6 +- srsepc/hdr/spgw/spgw.h | 18 +-- srsepc/src/mbms-gw/mbms-gw.cc | 8 +- srsepc/src/mme/nas.cc | 142 ++++++++---------- srsepc/src/mme/s1ap_nas_transport.cc | 50 +++--- srsepc/src/spgw/gtpc.cc | 8 +- srsepc/src/spgw/gtpu.cc | 22 +-- srsepc/src/spgw/spgw.cc | 2 +- 11 files changed, 122 insertions(+), 147 deletions(-) diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index 232a89f37..c93bc64e4 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -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 } } diff --git a/lib/include/srslte/interfaces/epc_interfaces.h b/lib/include/srslte/interfaces/epc_interfaces.h index bb3de8a0e..bf86d6743 100644 --- a/lib/include/srslte/interfaces/epc_interfaces.h +++ b/lib/include/srslte/interfaces/epc_interfaces.h @@ -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& pkt_queue) = 0; + virtual void send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid, + std::queue& 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 diff --git a/srsepc/hdr/spgw/gtpc.h b/srsepc/hdr/spgw/gtpc.h index 05f2e81cc..73f311013 100644 --- a/srsepc/hdr/spgw/gtpc.h +++ b/srsepc/hdr/spgw/gtpc.h @@ -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); diff --git a/srsepc/hdr/spgw/gtpu.h b/srsepc/hdr/spgw/gtpu.h index 9bb29f3b2..d7e570c74 100644 --- a/srsepc/hdr/spgw/gtpu.h +++ b/srsepc/hdr/spgw/gtpu.h @@ -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& pkt_queue); + virtual void send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid, + std::queue& pkt_queue); spgw* m_spgw; gtpc_interface_gtpu* m_gtpc; diff --git a/srsepc/hdr/spgw/spgw.h b/srsepc/hdr/spgw/spgw.h index 12af4db17..460acbfb6 100644 --- a/srsepc/hdr/spgw/spgw.h +++ b/srsepc/hdr/spgw/spgw.h @@ -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 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 paging_queue; } spgw_tunnel_ctx_t; class spgw : public srslte::thread diff --git a/srsepc/src/mbms-gw/mbms-gw.cc b/srsepc/src/mbms-gw/mbms-gw.cc index c5196df79..ea4c4b0c0 100644 --- a/srsepc/src/mbms-gw/mbms-gw.cc +++ b/srsepc/src/mbms-gw/mbms-gw.cc @@ -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; } diff --git a/srsepc/src/mme/nas.cc b/srsepc/src/mme/nas.cc index b083439d0..f4ca1725c 100644 --- a/srsepc/src/mme/nas.cc +++ b/srsepc/src/mme/nas.cc @@ -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"); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index f33601f66..ae751b0b0 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -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; } diff --git a/srsepc/src/spgw/gtpc.cc b/srsepc/src/spgw/gtpc.cc index 9e051f213..9fc18805a 100644 --- a/srsepc/src/spgw/gtpc.cc +++ b/srsepc/src/spgw/gtpc.cc @@ -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; diff --git a/srsepc/src/spgw/gtpu.cc b/srsepc/src/spgw/gtpu.cc index a6b762221..ba3a2ab04 100644 --- a/srsepc/src/spgw/gtpu.cc +++ b/srsepc/src/spgw/gtpu.cc @@ -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& pkt_queue) +void spgw::gtpu::send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid, + std::queue& 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; diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index 0c81dc18b..d07d72739 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -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");