From c37ab1de841631dd1802a2abbfde655f49513e12 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Wed, 4 Mar 2026 12:58:52 -0500 Subject: [PATCH] [fingerprint_grow] Fix OOB write and uint16 overflow (#14462) Co-authored-by: Claude Opus 4.6 --- .../fingerprint_grow/fingerprint_grow.cpp | 23 ++++++++++--------- .../fingerprint_grow/fingerprint_grow.h | 4 ++-- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/esphome/components/fingerprint_grow/fingerprint_grow.cpp b/esphome/components/fingerprint_grow/fingerprint_grow.cpp index da4535fc828..a633fbca282 100644 --- a/esphome/components/fingerprint_grow/fingerprint_grow.cpp +++ b/esphome/components/fingerprint_grow/fingerprint_grow.cpp @@ -361,7 +361,7 @@ void FingerprintGrowComponent::aura_led_control(uint8_t state, uint8_t speed, ui } } -uint8_t FingerprintGrowComponent::transfer_(std::vector *p_data_buffer) { +uint8_t FingerprintGrowComponent::transfer_(std::vector &data_buffer) { while (this->available()) this->read(); this->write((uint8_t) (START_CODE >> 8)); @@ -372,12 +372,12 @@ uint8_t FingerprintGrowComponent::transfer_(std::vector *p_data_buffer) this->write(this->address_[3]); this->write(COMMAND); - uint16_t wire_length = p_data_buffer->size() + 2; + uint16_t wire_length = data_buffer.size() + 2; this->write((uint8_t) (wire_length >> 8)); this->write((uint8_t) (wire_length & 0xFF)); uint16_t sum = (wire_length >> 8) + (wire_length & 0xFF) + COMMAND; - for (auto data : *p_data_buffer) { + for (auto data : data_buffer) { this->write(data); sum += data; } @@ -385,7 +385,7 @@ uint8_t FingerprintGrowComponent::transfer_(std::vector *p_data_buffer) this->write((uint8_t) (sum >> 8)); this->write((uint8_t) (sum & 0xFF)); - p_data_buffer->clear(); + data_buffer.clear(); uint8_t byte; uint16_t idx = 0, length = 0; @@ -431,9 +431,9 @@ uint8_t FingerprintGrowComponent::transfer_(std::vector *p_data_buffer) length |= byte; break; default: - p_data_buffer->push_back(byte); + data_buffer.push_back(byte); if ((idx - 8) == length) { - switch ((*p_data_buffer)[0]) { + switch (data_buffer[0]) { case OK: case NO_FINGER: case IMAGE_FAIL: @@ -453,25 +453,26 @@ uint8_t FingerprintGrowComponent::transfer_(std::vector *p_data_buffer) ESP_LOGE(TAG, "Reader failed to process request"); break; default: - ESP_LOGE(TAG, "Unknown response received from reader: 0x%.2X", (*p_data_buffer)[0]); + ESP_LOGE(TAG, "Unknown response received from reader: 0x%.2X", data_buffer[0]); break; } this->last_transfer_ms_ = millis(); - return (*p_data_buffer)[0]; + return data_buffer[0]; } break; } idx++; } ESP_LOGE(TAG, "No response received from reader"); - (*p_data_buffer)[0] = TIMEOUT; + data_buffer.clear(); + data_buffer.push_back(TIMEOUT); this->last_transfer_ms_ = millis(); return TIMEOUT; } uint8_t FingerprintGrowComponent::send_command_() { this->sensor_wakeup_(); - return this->transfer_(&this->data_); + return this->transfer_(this->data_); } void FingerprintGrowComponent::sensor_wakeup_() { @@ -517,7 +518,7 @@ void FingerprintGrowComponent::sensor_wakeup_() { std::vector buffer = {VERIFY_PASSWORD, (uint8_t) (this->password_ >> 24), (uint8_t) (this->password_ >> 16), (uint8_t) (this->password_ >> 8), (uint8_t) (this->password_ & 0xFF)}; - if (this->transfer_(&buffer) != OK) { + if (this->transfer_(buffer) != OK) { ESP_LOGE(TAG, "Wrong password"); } } diff --git a/esphome/components/fingerprint_grow/fingerprint_grow.h b/esphome/components/fingerprint_grow/fingerprint_grow.h index 370b26f56a3..db9d5ce564f 100644 --- a/esphome/components/fingerprint_grow/fingerprint_grow.h +++ b/esphome/components/fingerprint_grow/fingerprint_grow.h @@ -169,7 +169,7 @@ class FingerprintGrowComponent : public PollingComponent, public uart::UARTDevic bool set_password_(); bool get_parameters_(); void get_fingerprint_count_(); - uint8_t transfer_(std::vector *p_data_buffer); + uint8_t transfer_(std::vector &data_buffer); uint8_t send_command_(); void sensor_wakeup_(); void sensor_sleep_(); @@ -190,7 +190,7 @@ class FingerprintGrowComponent : public PollingComponent, public uart::UARTDevic bool is_sensor_awake_ = false; uint32_t last_transfer_ms_ = 0; uint32_t last_aura_led_control_ = 0; - uint16_t last_aura_led_duration_ = 0; + uint32_t last_aura_led_duration_ = 0; uint16_t system_identifier_code_ = 0; uint32_t idle_period_to_sleep_ms_ = UINT32_MAX; sensor::Sensor *fingerprint_count_sensor_{nullptr};