Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix memory leak in mbedtls by adjusting RX buffer size (issue #14444) (IDFGH-13752) #14614

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 17 additions & 11 deletions components/mbedtls/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,13 @@ menu "mbedTLS"
range 512 16384
depends on MBEDTLS_ASYMMETRIC_CONTENT_LEN
help
This defines maximum incoming fragment length, overriding default
maximum content length (MBEDTLS_SSL_MAX_CONTENT_LEN).
This defines the maximum incoming fragment length, overriding the default
maximum content length (MBEDTLS_SSL_MAX_CONTENT_LEN). The default value is
set to 16 KB as recommended by mbedTLS for secure handling of incoming messages.

Note: Setting this value lower than 16 KB may cause memory leaks or
unexpected behavior when receiving larger fragments, as there is no
mechanism to notify clients of buffer size restrictions.

config MBEDTLS_SSL_OUT_CONTENT_LEN
int "TLS maximum outgoing fragment length"
Expand All @@ -104,15 +109,16 @@ menu "mbedTLS"
# Dynamic buffer feature is not supported with DTLS
depends on !IDF_TARGET_LINUX && !MBEDTLS_SSL_PROTO_DTLS && !MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
help
Using dynamic TX/RX buffer. After enabling this option, mbedTLS will
allocate TX buffer when need to send data and then free it if all data
is sent, allocate RX buffer when need to receive data and then free it
when all data is used or read by upper layer.

By default, when SSL is initialized, mbedTLS also allocate TX and
RX buffer with the default value of "MBEDTLS_SSL_OUT_CONTENT_LEN" or
"MBEDTLS_SSL_IN_CONTENT_LEN", so to save more heap, users can set
the options to be an appropriate value.
Enable the dynamic TX/RX buffer for mbedTLS. When enabled, mbedTLS will
allocate the TX buffer only when data needs to be sent and free it once
the data is transmitted. Similarly, it will allocate the RX buffer when
receiving data and free it once the data has been fully processed.

Caution: For incoming data, the RX buffer size should respect the
minimum size of 16KB, as required by mbedTLS to prevent memory leaks and
ensure proper handling of incoming messages. Reducing the RX buffer
size may cause heap corruption or incomplete message processing if
larger fragments are received.

config MBEDTLS_DYNAMIC_FREE_CONFIG_DATA
bool "Free private key and DHM data after its usage"
Expand Down
8 changes: 7 additions & 1 deletion components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ static void esp_mbedtls_parse_record_header(mbedtls_ssl_context *ssl)
ssl->MBEDTLS_PRIVATE(in_msglen) = (ssl->MBEDTLS_PRIVATE(in_len)[0] << 8) | ssl->MBEDTLS_PRIVATE(in_len)[1];
}

static int rx_buffer_len(mbedtls_ssl_context *ssl)
{
(void)ssl;
return MBEDTLS_SSL_IN_BUFFER_LEN;
}

static int tx_buffer_len(mbedtls_ssl_context *ssl, int len)
{
(void)ssl;
Expand Down Expand Up @@ -358,7 +364,7 @@ int esp_mbedtls_add_rx_buffer(mbedtls_ssl_context *ssl)

in_left = ssl->MBEDTLS_PRIVATE(in_left);
in_msglen = ssl->MBEDTLS_PRIVATE(in_msglen);
buffer_len = tx_buffer_len(ssl, in_msglen);
buffer_len = rx_buffer_len(ssl);

ESP_LOGV(TAG, "message length is %d RX buffer length should be %d left is %d",
(int)in_msglen, (int)buffer_len, (int)ssl->MBEDTLS_PRIVATE(in_left));
Expand Down
6 changes: 3 additions & 3 deletions docs/en/api-reference/system/esp_https_ota.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ Please refer to :ref:`ESP-TLS: TLS Server Verification <esp_tls_server_verificat
Partial Image Download over HTTPS
---------------------------------

To use the partial image download feature, enable ``partial_http_download`` configuration in ``esp_https_ota_config_t``. When this configuration is enabled, firmware image will be downloaded in multiple HTTP requests of specified sizes. Maximum content length of each request can be specified by setting ``max_http_request_size`` to the required value.
To use the partial image download feature, enable partial_http_download configuration in esp_https_ota_config_t. When this configuration is enabled, the firmware image will be downloaded in multiple HTTP requests of specified sizes. Maximum content length of each request can be specified by setting max_http_request_size to the required value.

This option is useful while fetching image from a service like AWS S3, where mbedTLS Rx buffer size (:ref:`CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN`) can be set to a lower value which is not possible without enabling this configuration.
This option is useful while fetching an image from a service like AWS S3, where the mbedTLS RX buffer size (:ref:CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN) can be set to a lower value. However, note that reducing the buffer size below 16 KB may lead to memory leaks or unexpected behavior if the incoming fragment size exceeds the RX buffer capacity, as mbedTLS requires a minimum of 16KB for the RX buffer to ensure proper handling of incoming messages.

Default value of mbedTLS Rx buffer size is set to 16 KB. By using ``partial_http_download`` with ``max_http_request_size`` of 4 KB, size of mbedTLS Rx buffer can be reduced to 4 KB. With this configuration, memory saving of around 12 KB is expected.
By default, the mbedTLS RX buffer size is set to 16 KB. If the partial_http_download feature is used with a max_http_request_size of 4 KB, the RX buffer size can be reduced accordingly, but caution should be taken when using smaller buffer sizes.


Signature Verification
Expand Down