From be959d0575e8f7aec63fdd0d95bcfd0f99d7392a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 6 Mar 2018 12:46:02 +0100 Subject: [PATCH] Fix several pool leaks in RRC/NAS --- srsue/hdr/upper/rrc.h | 16 +++++----- srsue/src/upper/nas.cc | 26 +++++++++------- srsue/src/upper/rrc.cc | 69 ++++++++++++++++++++---------------------- 3 files changed, 56 insertions(+), 55 deletions(-) diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index 926e2bebe..55ee21097 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -295,9 +295,9 @@ private: LIBLTE_RRC_DL_CCCH_MSG_STRUCT dl_ccch_msg; LIBLTE_RRC_DL_DCCH_MSG_STRUCT dl_dcch_msg; - byte_buffer_t* byte_align_and_pack(byte_buffer_t *pdu = NULL); - void send_ul_ccch_msg(byte_buffer_t *pdu = NULL); - void send_ul_dcch_msg(byte_buffer_t *pdu = NULL); + byte_buffer_t* byte_align_and_pack(); + void send_ul_ccch_msg(); + void send_ul_dcch_msg(); srslte::bit_buffer_t bit_buf; pthread_mutex_t mutex; @@ -532,10 +532,10 @@ private: void send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause, uint16_t crnti); void send_con_restablish_complete(); void send_con_setup_complete(byte_buffer_t *nas_msg); - void send_ul_info_transfer(uint32_t lcid, byte_buffer_t *sdu); - void send_security_mode_complete(uint32_t lcid, byte_buffer_t *pdu); - void send_rrc_con_reconfig_complete(byte_buffer_t *pdu); - void send_rrc_ue_cap_info(byte_buffer_t *pdu); + void send_ul_info_transfer(byte_buffer_t *nas_msg); + void send_security_mode_complete(); + void send_rrc_con_reconfig_complete(); + void send_rrc_ue_cap_info(); // Parsers void parse_dl_ccch(byte_buffer_t *pdu); @@ -562,7 +562,7 @@ private: void apply_sib2_configs(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2); void handle_con_setup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *setup); void handle_con_reest(LIBLTE_RRC_CONNECTION_REESTABLISHMENT_STRUCT *setup); - void handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT *reconfig, byte_buffer_t *pdu); + void handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT *reconfig); void add_srb(LIBLTE_RRC_SRB_TO_ADD_MOD_STRUCT *srb_cnfg); void add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg); void release_drb(uint8_t lcid); diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 8a05595c7..42dae8fc1 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -222,7 +222,7 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { default: nas_log->error("Not handling NAS message with SEC_HDR_TYPE=%02X\n", sec_hdr_type); pool->deallocate(pdu); - break; + return; } // Write NAS pcap @@ -266,7 +266,7 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { default: nas_log->error("Not handling NAS message with MSG_TYPE=%02X\n", msg_type); pool->deallocate(pdu); - break; + return; } } @@ -547,6 +547,8 @@ void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) { act_def_eps_bearer_context_accept.protocol_cnfg_opts_present = false; liblte_mme_pack_activate_default_eps_bearer_context_accept_msg(&act_def_eps_bearer_context_accept, &attach_complete.esm_msg); + + pdu->reset(); liblte_mme_pack_attach_complete_msg(&attach_complete, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, ctxt.tx_count, @@ -762,36 +764,37 @@ void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu) } // Send response - byte_buffer_t *sdu = pool_allocate; + pdu->reset(); liblte_mme_pack_security_mode_complete_msg(&sec_mode_comp, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT, ctxt.tx_count, - (LIBLTE_BYTE_MSG_STRUCT *) sdu); + (LIBLTE_BYTE_MSG_STRUCT *) pdu); if(pcap != NULL) { - pcap->write_nas(sdu->msg, sdu->N_bytes); + pcap->write_nas(pdu->msg, pdu->N_bytes); } - cipher_encrypt(sdu); + cipher_encrypt(pdu); integrity_generate(&k_nas_int[16], ctxt.tx_count, SECURITY_DIRECTION_UPLINK, - &sdu->msg[5], - sdu->N_bytes - 5, - &sdu->msg[1]); + &pdu->msg[5], + pdu->N_bytes - 5, + &pdu->msg[1]); nas_log->info("Sending Security Mode Complete nas_current_ctxt.tx_count=%d, RB=%s\n", ctxt.tx_count, rrc->get_rb_name(lcid).c_str()); - rrc->write_sdu(lcid, sdu); + rrc->write_sdu(lcid, pdu); ctxt.tx_count++; pool->deallocate(pdu); } void nas::parse_service_reject(uint32_t lcid, byte_buffer_t *pdu) { nas_log->error("TODO:parse_service_reject\n"); + pool->deallocate(pdu); } void nas::parse_esm_information_request(uint32_t lcid, byte_buffer_t *pdu) { nas_log->error("TODO:parse_esm_information_request\n"); - + pool->deallocate(pdu); } void nas::parse_emm_information(uint32_t lcid, byte_buffer_t *pdu) { @@ -800,6 +803,7 @@ void nas::parse_emm_information(uint32_t lcid, byte_buffer_t *pdu) { nas_log->info("Received EMM Information: %s\n", str.c_str()); nas_log->console("%s\n", str.c_str()); ctxt.rx_count++; + pool->deallocate(pdu); } /******************************************************************************* diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 11cb432fa..7c2798658 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1070,34 +1070,36 @@ void rrc::send_con_setup_complete(byte_buffer_t *nas_msg) { send_ul_dcch_msg(); } -void rrc::send_ul_info_transfer(uint32_t lcid, byte_buffer_t *sdu) { +void rrc::send_ul_info_transfer(byte_buffer_t *nas_msg) { rrc_log->debug("Preparing RX Info Transfer\n"); // Prepare RX INFO packet ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_UL_INFO_TRANSFER; ul_dcch_msg.msg.ul_info_transfer.dedicated_info_type = LIBLTE_RRC_UL_INFORMATION_TRANSFER_TYPE_NAS; - memcpy(ul_dcch_msg.msg.ul_info_transfer.dedicated_info.msg, sdu->msg, sdu->N_bytes); - ul_dcch_msg.msg.ul_info_transfer.dedicated_info.N_bytes = sdu->N_bytes; + memcpy(ul_dcch_msg.msg.ul_info_transfer.dedicated_info.msg, nas_msg->msg, nas_msg->N_bytes); + ul_dcch_msg.msg.ul_info_transfer.dedicated_info.N_bytes = nas_msg->N_bytes; - send_ul_dcch_msg(sdu); + pool->deallocate(nas_msg); + + send_ul_dcch_msg(); } -void rrc::send_security_mode_complete(uint32_t lcid, byte_buffer_t *pdu) { +void rrc::send_security_mode_complete() { rrc_log->debug("Preparing Security Mode Complete\n"); ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_SECURITY_MODE_COMPLETE; ul_dcch_msg.msg.security_mode_complete.rrc_transaction_id = transaction_id; - send_ul_dcch_msg(pdu); + send_ul_dcch_msg(); } -void rrc::send_rrc_con_reconfig_complete(byte_buffer_t *pdu) { +void rrc::send_rrc_con_reconfig_complete() { rrc_log->debug("Preparing RRC Connection Reconfig Complete\n"); ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_RRC_CON_RECONFIG_COMPLETE; ul_dcch_msg.msg.rrc_con_reconfig_complete.rrc_transaction_id = transaction_id; - send_ul_dcch_msg(pdu); + send_ul_dcch_msg(); } bool rrc::ho_prepare() { @@ -1177,7 +1179,7 @@ bool rrc::ho_prepare() { k_rrc_enc, k_rrc_int, k_up_enc, k_up_int, cipher_algo, integ_algo); pdcp->config_security_all(k_rrc_enc, k_rrc_int, cipher_algo, integ_algo); - send_rrc_con_reconfig_complete(NULL); + send_rrc_con_reconfig_complete(); } return true; } @@ -1229,15 +1231,14 @@ void rrc::ho_failed() { send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_HANDOVER_FAILURE, ho_src_rnti); } -void rrc::handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT *reconfig, - byte_buffer_t *pdu) { +void rrc::handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT *reconfig) { uint32_t i; if (reconfig->mob_ctrl_info_present) { if (reconfig->mob_ctrl_info.target_pci == phy->get_current_pci()) { rrc_log->warning("Received HO command to own cell\n"); - send_rrc_con_reconfig_complete(pdu); + send_rrc_con_reconfig_complete(); } else { rrc_log->info("Received HO command to target PCell=%d\n", reconfig->mob_ctrl_info.target_pci); rrc_log->console("Received HO command to target PCell=%d, NCC=%d\n", @@ -1259,7 +1260,7 @@ void rrc::handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGU measurements.parse_meas_config(&reconfig->meas_cnfg); } - send_rrc_con_reconfig_complete(pdu); + send_rrc_con_reconfig_complete(); byte_buffer_t *nas_sdu; for (i = 0; i < reconfig->N_ded_info_nas; i++) { @@ -1318,10 +1319,10 @@ void rrc::leave_connected() * *******************************************************************************/ void rrc::write_pdu_bcch_bch(byte_buffer_t *pdu) { - pool->deallocate(pdu); if (state == RRC_STATE_PLMN_SELECTION) { // Do we need to do something with BCH? rrc_log->info_hex(pdu->msg, pdu->N_bytes, "BCCH BCH message received."); + pool->deallocate(pdu); } else { rrc_log->warning("Received BCCH BCH in incorrect state\n"); } @@ -1523,7 +1524,7 @@ void rrc::write_pdu_pcch(byte_buffer_t *pdu) { * * *******************************************************************************/ -byte_buffer_t* rrc::byte_align_and_pack(byte_buffer_t *pdu) +byte_buffer_t* rrc::byte_align_and_pack() { // Byte align and pack the message bits for PDCP if ((bit_buf.N_bits % 8) != 0) { @@ -1533,15 +1534,8 @@ byte_buffer_t* rrc::byte_align_and_pack(byte_buffer_t *pdu) } // Reset and reuse sdu buffer if provided - byte_buffer_t *pdcp_buf = pdu; - + byte_buffer_t *pdcp_buf = pool_allocate; if (pdcp_buf) { - pdcp_buf->reset(); - } else { - pdcp_buf = pool_allocate; - } - - if (pdcp_buf != NULL) { srslte_bit_pack_vector(bit_buf.msg, pdcp_buf->msg, bit_buf.N_bits); pdcp_buf->N_bytes = bit_buf.N_bits / 8; pdcp_buf->set_timestamp(); @@ -1551,10 +1545,10 @@ byte_buffer_t* rrc::byte_align_and_pack(byte_buffer_t *pdu) return pdcp_buf; } -void rrc::send_ul_ccch_msg(byte_buffer_t *pdu) +void rrc::send_ul_ccch_msg() { liblte_rrc_pack_ul_ccch_msg(&ul_ccch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); - pdu = byte_align_and_pack(pdu); + byte_buffer_t *pdu = byte_align_and_pack(); if (pdu) { // Set UE contention resolution ID in MAC uint64_t uecri = 0; @@ -1572,11 +1566,10 @@ void rrc::send_ul_ccch_msg(byte_buffer_t *pdu) } } -void rrc::send_ul_dcch_msg(byte_buffer_t *pdu) +void rrc::send_ul_dcch_msg() { liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); - - pdu = byte_align_and_pack(pdu); + byte_buffer_t *pdu = byte_align_and_pack(); if (pdu) { rrc_log->info("Sending %s\n", liblte_rrc_ul_dcch_msg_type_text[ul_dcch_msg.msg_type]); pdcp->write_sdu(RB_ID_SRB1, pdu); @@ -1591,7 +1584,7 @@ void rrc::write_sdu(uint32_t lcid, byte_buffer_t *sdu) { send_con_setup_complete(sdu); break; case RRC_STATE_CONNECTED: - send_ul_info_transfer(lcid, sdu); + send_ul_info_transfer(sdu); break; default: rrc_log->error("SDU received from NAS while RRC state = %s\n", rrc_state_text[state]); @@ -1665,11 +1658,15 @@ void rrc::parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu) { get_rb_name(lcid).c_str(), liblte_rrc_dl_dcch_msg_type_text[dl_dcch_msg.msg_type]); - // Reset and reuse pdu buffer if possible - pdu->reset(); + pool->deallocate(pdu); switch (dl_dcch_msg.msg_type) { case LIBLTE_RRC_DL_DCCH_MSG_TYPE_DL_INFO_TRANSFER: + pdu = pool_allocate; + if (!pdu) { + rrc_log->error("Fatal error: out of buffers in pool\n"); + return; + } memcpy(pdu->msg, dl_dcch_msg.msg.dl_info_transfer.dedicated_info.msg, dl_dcch_msg.msg.dl_info_transfer.dedicated_info.N_bytes); pdu->N_bytes = dl_dcch_msg.msg.dl_info_transfer.dedicated_info.N_bytes; @@ -1696,18 +1693,18 @@ void rrc::parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu) { // Configure PDCP for security pdcp->config_security(lcid, k_rrc_enc, k_rrc_int, cipher_algo, integ_algo); pdcp->enable_integrity(lcid); - send_security_mode_complete(lcid, pdu); + send_security_mode_complete(); pdcp->enable_encryption(lcid); break; case LIBLTE_RRC_DL_DCCH_MSG_TYPE_RRC_CON_RECONFIG: transaction_id = dl_dcch_msg.msg.rrc_con_reconfig.rrc_transaction_id; - handle_rrc_con_reconfig(lcid, &dl_dcch_msg.msg.rrc_con_reconfig, pdu); + handle_rrc_con_reconfig(lcid, &dl_dcch_msg.msg.rrc_con_reconfig); break; case LIBLTE_RRC_DL_DCCH_MSG_TYPE_UE_CAPABILITY_ENQUIRY: transaction_id = dl_dcch_msg.msg.ue_cap_enquiry.rrc_transaction_id; for (uint32_t i = 0; i < dl_dcch_msg.msg.ue_cap_enquiry.N_ue_cap_reqs; i++) { if (LIBLTE_RRC_RAT_TYPE_EUTRA == dl_dcch_msg.msg.ue_cap_enquiry.ue_capability_request[i]) { - send_rrc_ue_cap_info(pdu); + send_rrc_ue_cap_info(); break; } } @@ -1743,7 +1740,7 @@ void rrc::enable_capabilities() { phy->set_config_64qam_en(enable_ul_64); } -void rrc::send_rrc_ue_cap_info(byte_buffer_t *pdu) { +void rrc::send_rrc_ue_cap_info() { rrc_log->debug("Preparing UE Capability Info\n"); ul_dcch_msg.msg_type = LIBLTE_RRC_UL_DCCH_MSG_TYPE_UE_CAPABILITY_INFO; @@ -1792,7 +1789,7 @@ void rrc::send_rrc_ue_cap_info(byte_buffer_t *pdu) { liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf); - send_ul_dcch_msg(pdu); + send_ul_dcch_msg(); }