[multiple] Fix crashes from malformed external input (batch 2) (#14651)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jonathan Swoboda
2026-03-09 17:20:09 -04:00
committed by GitHub
parent 9418f35cc3
commit fecedeb018
6 changed files with 46 additions and 1 deletions

View File

@@ -514,6 +514,11 @@ void ESPBTDevice::parse_adv_(const uint8_t *payload, uint8_t len) {
continue; // Possible zero padded advertisement data
}
// Validate field fits in remaining payload
if (offset + field_length > len) {
break;
}
// first byte of adv record is adv record type
const uint8_t record_type = payload[offset++];
const uint8_t *record = &payload[offset];

View File

@@ -59,6 +59,10 @@ bool ModbusController::send_next_command_() {
// Queue incoming response
void ModbusController::on_modbus_data(const std::vector<uint8_t> &data) {
if (this->command_queue_.empty()) {
ESP_LOGW(TAG, "Received modbus data but command queue is empty");
return;
}
auto &current_command = this->command_queue_.front();
if (current_command != nullptr) {
if (this->module_offline_) {
@@ -92,6 +96,9 @@ void ModbusController::process_modbus_data_(const ModbusCommandItem *response) {
void ModbusController::on_modbus_error(uint8_t function_code, uint8_t exception_code) {
ESP_LOGE(TAG, "Modbus error function code: 0x%X exception: %d ", function_code, exception_code);
if (this->command_queue_.empty()) {
return;
}
// Remove pending command waiting for a response
auto &current_command = this->command_queue_.front();
if (current_command != nullptr) {
@@ -175,6 +182,11 @@ void ModbusController::on_modbus_write_registers(uint8_t function_code, const st
uint16_t payload_offset;
if (function_code == ModbusFunctionCode::WRITE_MULTIPLE_REGISTERS) {
if (data.size() < 5) {
ESP_LOGW(TAG, "Write multiple registers data too short (%zu bytes)", data.size());
this->send_error(function_code, ModbusExceptionCode::ILLEGAL_DATA_VALUE);
return;
}
number_of_registers = uint16_t(data[3]) | (uint16_t(data[2]) << 8);
if (number_of_registers == 0 || number_of_registers > modbus::MAX_NUM_OF_REGISTERS_TO_WRITE) {
ESP_LOGW(TAG, "Invalid number of registers %d. Sending exception response.", number_of_registers);
@@ -188,8 +200,19 @@ void ModbusController::on_modbus_write_registers(uint8_t function_code, const st
this->send_error(function_code, ModbusExceptionCode::ILLEGAL_DATA_VALUE);
return;
}
if (data.size() < 5 + payload_size) {
ESP_LOGW(TAG, "Write multiple registers payload truncated (%zu bytes, expected %u)", data.size(),
5 + payload_size);
this->send_error(function_code, ModbusExceptionCode::ILLEGAL_DATA_VALUE);
return;
}
payload_offset = 5;
} else if (function_code == ModbusFunctionCode::WRITE_SINGLE_REGISTER) {
if (data.size() < 4) {
ESP_LOGW(TAG, "Write single register data too short (%zu bytes)", data.size());
this->send_error(function_code, ModbusExceptionCode::ILLEGAL_DATA_VALUE);
return;
}
number_of_registers = 1;
payload_offset = 2;
} else {

View File

@@ -86,6 +86,12 @@ int Nextion::upload_by_chunks_(HTTPClient &http_client, uint32_t &range_start) {
ESP_LOGD(TAG, "Upload: %0.2f%% (%" PRIu32 " left, heap: %" PRIu32 ")", upload_percentage, this->content_length_,
EspClass::getFreeHeap());
upload_first_chunk_sent_ = true;
if (recv_string.empty()) {
ESP_LOGW(TAG, "No response from display during upload");
allocator.deallocate(buffer, 4096);
buffer = nullptr;
return -1;
}
if (recv_string[0] == 0x08 && recv_string.size() == 5) { // handle partial upload request
char hex_buf[format_hex_pretty_size(NEXTION_MAX_RESPONSE_LOG_BYTES)];
ESP_LOGD(

View File

@@ -108,6 +108,12 @@ int Nextion::upload_by_chunks_(esp_http_client_handle_t http_client, uint32_t &r
static_cast<uint32_t>(esp_get_free_heap_size()));
#endif
upload_first_chunk_sent_ = true;
if (recv_string.empty()) {
ESP_LOGW(TAG, "No response from display during upload");
allocator.deallocate(buffer, 4096);
buffer = nullptr;
return -1;
}
if (recv_string[0] == 0x08 && recv_string.size() == 5) { // handle partial upload request
char hex_buf[format_hex_pretty_size(NEXTION_MAX_RESPONSE_LOG_BYTES)];
ESP_LOGD(

View File

@@ -199,7 +199,7 @@ void MR60BHA2Component::process_frame_(uint16_t frame_id, uint16_t frame_type, c
}
break;
case DISTANCE_TYPE_BUFFER:
if (data[0] != 0) {
if (length >= 1 && data[0] != 0) {
if (this->distance_sensor_ != nullptr && length >= 8) {
uint32_t current_distance_int = encode_uint32(data[7], data[6], data[5], data[4]);
float distance_float;

View File

@@ -492,6 +492,11 @@ bool USBClient::transfer_in(uint8_t ep_address, const transfer_cb_t &callback, u
ESP_LOGE(TAG, "Too many requests queued");
return false;
}
if (length > trq->transfer->data_buffer_size) {
ESP_LOGE(TAG, "transfer_in: data length %u exceeds buffer size %u", length, trq->transfer->data_buffer_size);
this->release_trq(trq);
return false;
}
trq->callback = callback;
trq->transfer->callback = transfer_callback;
trq->transfer->bEndpointAddress = ep_address | USB_DIR_IN;