mirror of https://github.com/PentHertz/srsLTE.git
pdcp: drop PDCP control PDUs
this patch adds a check to drop all PDCP control PDUs in order to prevent handling them as data PDUs. This could happen when the size exceeded the arbitrary length check. This should fix #1787
This commit is contained in:
parent
b3eb9651d6
commit
795db30338
|
@ -43,6 +43,13 @@ const uint8_t PDCP_SN_LEN_18 = 18;
|
|||
|
||||
typedef enum { PDCP_RB_IS_SRB, PDCP_RB_IS_DRB } pdcp_rb_type_t;
|
||||
|
||||
enum pdcp_dc_field_t {
|
||||
PDCP_DC_FIELD_CONTROL_PDU = 0,
|
||||
PDCP_DC_FIELD_DATA_PDU,
|
||||
PDCP_DC_FIELD_N_ITEMS,
|
||||
};
|
||||
static const char* pdcp_dc_field_text[PDCP_DC_FIELD_N_ITEMS] = {"Control PDU", "Data PDU"};
|
||||
|
||||
// Taken from PDCP-Config (TS 38.331 version 15.2.1)
|
||||
enum class pdcp_t_reordering_t {
|
||||
ms0 = 0,
|
||||
|
|
|
@ -158,6 +158,7 @@ protected:
|
|||
void cipher_decrypt(uint8_t* ct, uint32_t ct_len, uint32_t count, uint8_t* msg);
|
||||
|
||||
// Common packing functions
|
||||
bool is_control_pdu(const unique_byte_buffer_t& pdu);
|
||||
uint32_t read_data_header(const unique_byte_buffer_t& pdu);
|
||||
void discard_data_header(const unique_byte_buffer_t& pdu);
|
||||
void write_data_header(const srslte::unique_byte_buffer_t& sdu, uint32_t count);
|
||||
|
|
|
@ -27,8 +27,7 @@
|
|||
namespace srslte {
|
||||
|
||||
pdcp_entity_base::pdcp_entity_base(task_sched_handle task_sched_, srslte::log_ref log_) :
|
||||
log(log_),
|
||||
task_sched(task_sched_)
|
||||
log(log_), task_sched(task_sched_)
|
||||
{}
|
||||
|
||||
pdcp_entity_base::~pdcp_entity_base() {}
|
||||
|
@ -218,6 +217,13 @@ void pdcp_entity_base::cipher_decrypt(uint8_t* ct, uint32_t ct_len, uint32_t cou
|
|||
/****************************************************************************
|
||||
* Common pack functions
|
||||
***************************************************************************/
|
||||
|
||||
bool pdcp_entity_base::is_control_pdu(const unique_byte_buffer_t& pdu)
|
||||
{
|
||||
const uint8_t* payload = pdu->msg;
|
||||
return ((*(payload) >> 7) & 0x01) == PDCP_DC_FIELD_CONTROL_PDU;
|
||||
}
|
||||
|
||||
uint32_t pdcp_entity_base::read_data_header(const unique_byte_buffer_t& pdu)
|
||||
{
|
||||
// Check PDU is long enough to extract header
|
||||
|
@ -273,7 +279,7 @@ void pdcp_entity_base::write_data_header(const srslte::unique_byte_buffer_t& sdu
|
|||
sdu->msg[0] = SN(count); // Data PDU and SN LEN 5 implies SRB, D flag must not be present
|
||||
break;
|
||||
case PDCP_SN_LEN_7:
|
||||
sdu->msg[0] = SN(count);
|
||||
sdu->msg[0] = SN(count);
|
||||
if (is_drb()) {
|
||||
sdu->msg[0] |= 0x80; // On Data PDUs for DRBs we must set the D flag.
|
||||
}
|
||||
|
|
|
@ -31,10 +31,7 @@ pdcp_entity_lte::pdcp_entity_lte(srsue::rlc_interface_pdcp* rlc_,
|
|||
srslte::log_ref log_,
|
||||
uint32_t lcid_,
|
||||
pdcp_config_t cfg_) :
|
||||
pdcp_entity_base(task_sched_, log_),
|
||||
rlc(rlc_),
|
||||
rrc(rrc_),
|
||||
gw(gw_)
|
||||
pdcp_entity_base(task_sched_, log_), rlc(rlc_), rrc(rrc_), gw(gw_)
|
||||
{
|
||||
lcid = lcid_;
|
||||
cfg = cfg_;
|
||||
|
@ -161,6 +158,12 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu)
|
|||
// RLC interface
|
||||
void pdcp_entity_lte::write_pdu(unique_byte_buffer_t pdu)
|
||||
{
|
||||
// drop control PDUs
|
||||
if (is_drb() && is_control_pdu(pdu)) {
|
||||
log->info("Dropping PDCP control PDU\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
if (pdu->N_bytes <= cfg.hdr_len_bytes) {
|
||||
log->error("PDCP PDU smaller than required header size.\n");
|
||||
|
|
Loading…
Reference in New Issue