fix various potential buffer overruns

this is based on suggested fixes by Dirk Grabinski and David who
have fuzzed various parts of srsLTE using afl
master
Andre Puschmann 6 years ago
parent 701db61fde
commit 62a4fa1c93

@ -711,6 +711,10 @@ dyn_octstring& dyn_octstring::from_string(const std::string& hexstr)
SRSASN_CODE pack_common_bitstring(bit_ref& bref, const uint8_t* buf, uint32_t nbits) SRSASN_CODE pack_common_bitstring(bit_ref& bref, const uint8_t* buf, uint32_t nbits)
{ {
uint32_t n_octs = (uint32_t)ceilf(nbits / 8.0f); uint32_t n_octs = (uint32_t)ceilf(nbits / 8.0f);
if (n_octs == 0) {
srsasn_log_print(LOG_LEVEL_ERROR, "Invalid number of octets (%d)\n", n_octs);
return SRSASN_ERROR_DECODE_FAIL;
}
uint32_t offset = ((nbits - 1) % 8) + 1; uint32_t offset = ((nbits - 1) % 8) + 1;
HANDLE_CODE(bref.pack(buf[n_octs - 1], offset)); HANDLE_CODE(bref.pack(buf[n_octs - 1], offset));
for (uint32_t i = 1; i < n_octs; ++i) { for (uint32_t i = 1; i < n_octs; ++i) {
@ -722,6 +726,10 @@ SRSASN_CODE pack_common_bitstring(bit_ref& bref, const uint8_t* buf, uint32_t nb
SRSASN_CODE unpack_common_bitstring(uint8_t* buf, bit_ref& bref, uint32_t nbits) SRSASN_CODE unpack_common_bitstring(uint8_t* buf, bit_ref& bref, uint32_t nbits)
{ {
uint32_t n_octs = (uint32_t)ceilf(nbits / 8.0f); uint32_t n_octs = (uint32_t)ceilf(nbits / 8.0f);
if (n_octs == 0) {
srsasn_log_print(LOG_LEVEL_ERROR, "Invalid number of octets (%d)\n", n_octs);
return SRSASN_ERROR_DECODE_FAIL;
}
uint32_t offset = ((nbits - 1) % 8) + 1; uint32_t offset = ((nbits - 1) % 8) + 1;
HANDLE_CODE(bref.unpack(buf[n_octs - 1], offset)); HANDLE_CODE(bref.unpack(buf[n_octs - 1], offset));
for (uint32_t i = 1; i < n_octs; ++i) { for (uint32_t i = 1; i < n_octs; ++i) {
@ -948,6 +956,11 @@ SRSASN_CODE ext_groups_header::pack_nof_groups(bit_ref& bref) const
SRSASN_CODE ext_groups_header::pack_group_flags(bit_ref& bref) const SRSASN_CODE ext_groups_header::pack_group_flags(bit_ref& bref) const
{ {
if (nof_groups > groups.size()) {
srsasn_log_print(LOG_LEVEL_ERROR, "Exceeded maximum number of groups (%d>%d)\n", nof_groups, groups.size());
return SRSASN_ERROR_ENCODE_FAIL;
}
// NOTE: nof_groups is cached // NOTE: nof_groups is cached
for (uint32_t i = 0; i < nof_groups; ++i) { for (uint32_t i = 0; i < nof_groups; ++i) {
HANDLE_CODE(bref.pack(groups[i], 1)); HANDLE_CODE(bref.pack(groups[i], 1));
@ -974,6 +987,10 @@ SRSASN_CODE ext_groups_header::unpack_nof_groups(bit_ref& bref)
SRSASN_CODE ext_groups_header::unpack_group_flags(bit_ref& bref) SRSASN_CODE ext_groups_header::unpack_group_flags(bit_ref& bref)
{ {
if (nof_groups > groups.size()) {
srsasn_log_print(LOG_LEVEL_ERROR, "Exceeded maximum number of groups (%d>%d)\n", nof_groups, groups.size());
return SRSASN_ERROR_DECODE_FAIL;
}
for (uint32_t i = 0; i < nof_groups; ++i) { for (uint32_t i = 0; i < nof_groups; ++i) {
HANDLE_CODE(bref.unpack(groups[i], 1)); HANDLE_CODE(bref.unpack(groups[i], 1));
} }

@ -1697,7 +1697,8 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_esm_message_container_ie(LIBLTE_BYTE_MSG_STRUC
uint32 i; uint32 i;
if(esm_msg != NULL && if(esm_msg != NULL &&
ie_ptr != NULL) ie_ptr != NULL &&
esm_msg->N_bytes <= LIBLTE_MAX_MSG_SIZE_BYTES)
{ {
(*ie_ptr)[0] = esm_msg->N_bytes >> 8; (*ie_ptr)[0] = esm_msg->N_bytes >> 8;
(*ie_ptr)[1] = esm_msg->N_bytes & 0xFF; (*ie_ptr)[1] = esm_msg->N_bytes & 0xFF;
@ -1723,6 +1724,11 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_esm_message_container_ie(uint8
{ {
esm_msg->N_bytes = (*ie_ptr)[0] << 8; esm_msg->N_bytes = (*ie_ptr)[0] << 8;
esm_msg->N_bytes |= (*ie_ptr)[1]; esm_msg->N_bytes |= (*ie_ptr)[1];
if(esm_msg->N_bytes > LIBLTE_MAX_MSG_SIZE_BYTES ) {
return err;
}
for(i=0; i<esm_msg->N_bytes; i++) for(i=0; i<esm_msg->N_bytes; i++)
{ {
esm_msg->msg[i] = (*ie_ptr)[2+i]; esm_msg->msg[i] = (*ie_ptr)[2+i];
@ -3406,6 +3412,11 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_emergency_number_list_ie(LIBLTE_MME_EMERGENCY_
{ {
(*ie_ptr)[length++] = (emerg_num_list->emerg_num[i].N_emerg_num_digits/2) + 1; (*ie_ptr)[length++] = (emerg_num_list->emerg_num[i].N_emerg_num_digits/2) + 1;
(*ie_ptr)[length++] = emerg_num_list->emerg_num[i].emerg_service_cat; (*ie_ptr)[length++] = emerg_num_list->emerg_num[i].emerg_service_cat;
if (emerg_num_list->emerg_num[i].N_emerg_num_digits / 2 > LIBLTE_MME_EMERGENCY_NUMBER_MAX_NUM_DIGITS) {
return err;
}
for(j=0; j<emerg_num_list->emerg_num[i].N_emerg_num_digits/2; j++) for(j=0; j<emerg_num_list->emerg_num[i].N_emerg_num_digits/2; j++)
{ {
(*ie_ptr)[length] = emerg_num_list->emerg_num[i].emerg_num[j*2+0]; (*ie_ptr)[length] = emerg_num_list->emerg_num[i].emerg_num[j*2+0];
@ -3449,6 +3460,11 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_emergency_number_list_ie(uint8
{ {
idx = emerg_num_list->N_emerg_nums; idx = emerg_num_list->N_emerg_nums;
emerg_num_list->emerg_num[idx].N_emerg_num_digits = ((*ie_ptr)[length++] - 1) * 2; emerg_num_list->emerg_num[idx].N_emerg_num_digits = ((*ie_ptr)[length++] - 1) * 2;
if (emerg_num_list->emerg_num[idx].N_emerg_num_digits >
LIBLTE_MME_EMERGENCY_NUMBER_MAX_NUM_DIGITS) {
return err;
}
emerg_num_list->emerg_num[idx].emerg_service_cat = (LIBLTE_MME_EMERGENCY_SERVICE_CATEGORY_ENUM)((*ie_ptr)[length++] & 0x1F); emerg_num_list->emerg_num[idx].emerg_service_cat = (LIBLTE_MME_EMERGENCY_SERVICE_CATEGORY_ENUM)((*ie_ptr)[length++] & 0x1F);
for(i=0; i<emerg_num_list->emerg_num[idx].N_emerg_num_digits/2; i++) for(i=0; i<emerg_num_list->emerg_num[idx].N_emerg_num_digits/2; i++)
{ {
@ -3629,7 +3645,8 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_generic_message_container_ie(LIBLTE_BYTE_MSG_S
uint32 i; uint32 i;
if(msg != NULL && if(msg != NULL &&
ie_ptr != NULL) ie_ptr != NULL &&
msg->N_bytes <= LIBLTE_MAX_MSG_SIZE_BYTES)
{ {
(*ie_ptr)[0] = msg->N_bytes >> 8; (*ie_ptr)[0] = msg->N_bytes >> 8;
(*ie_ptr)[1] = msg->N_bytes & 0xFF; (*ie_ptr)[1] = msg->N_bytes & 0xFF;
@ -3655,6 +3672,11 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_generic_message_container_ie(uint8
{ {
msg->N_bytes = (*ie_ptr)[0] << 8; msg->N_bytes = (*ie_ptr)[0] << 8;
msg->N_bytes |= (*ie_ptr)[1]; msg->N_bytes |= (*ie_ptr)[1];
if(msg->N_bytes > LIBLTE_MAX_MSG_SIZE_BYTES){
return err;
}
for(i=0; i<msg->N_bytes; i++) for(i=0; i<msg->N_bytes; i++)
{ {
msg->msg[i] = (*ie_ptr)[2+i]; msg->msg[i] = (*ie_ptr)[2+i];

@ -123,9 +123,8 @@ void s1ap::run_thread()
// S1AP rx loop // S1AP rx loop
while(running) { while(running) {
pdu->clear(); pdu->clear();
pdu->N_bytes = recv(socket_fd, pdu->msg, sz, 0); ssize_t n_recv = recv(socket_fd, pdu->msg, sz, 0);
if (n_recv <= 0) {
if(pdu->N_bytes <= 0) {
mme_connected = false; mme_connected = false;
do { do {
s1ap_log->error("Disconnected - attempting reconnection in 10 seconds\n"); s1ap_log->error("Disconnected - attempting reconnection in 10 seconds\n");
@ -141,6 +140,8 @@ void s1ap::run_thread()
} }
} }
pdu->N_bytes = static_cast<uint32_t>(n_recv);
s1ap_log->info_hex(pdu->msg, pdu->N_bytes, "Received S1AP PDU"); s1ap_log->info_hex(pdu->msg, pdu->N_bytes, "Received S1AP PDU");
handle_s1ap_rx_pdu(pdu.get()); handle_s1ap_rx_pdu(pdu.get());
} }

Loading…
Cancel
Save