Introduce function to return size of buffer needed for reassembly
A previous commit introduced the function ssl_prepare_reassembly_buffer()
which took a message length and a boolean flag indicating if a reassembly
bit map was needed, and attempted to heap-allocate a buffer of sufficient
size to hold both the message, its header, and potentially the reassembly
bitmap.
A subsequent commit is going to introduce a limit on the amount of heap
allocations allowed for the purpose of buffering, and this change will
need to know the reassembly buffer size before attempting the allocation.
To this end, this commit changes ssl_prepare_reassembly_buffer() into
ssl_get_reassembly_buffer_size() which solely computes the reassembly
buffer size, and performing the heap allocation manually in
ssl_buffer_message().
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 4b64fe6..7eb1c89 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -3523,28 +3523,10 @@
}
/* msg_len does not include the handshake header */
-static int ssl_prepare_reassembly_buffer( mbedtls_ssl_context *ssl, /* debug */
- unsigned msg_len,
- unsigned add_bitmap,
- unsigned char **target )
+static size_t ssl_get_reassembly_buffer_size( unsigned msg_len,
+ unsigned add_bitmap )
{
size_t alloc_len;
- unsigned char *buf;
-
-#if !defined(MBEDTLS_DEBUG_C)
- /* The SSL context is used for debugging only. */
- ((void) ssl);
-#endif
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialize reassembly, total length = %d",
- msg_len ) );
-
- /* NOTE: That should be checked earlier */
- if( msg_len > MBEDTLS_SSL_IN_CONTENT_LEN )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too large" ) );
- return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
- }
alloc_len = 12; /* Handshake header */
alloc_len += msg_len; /* Content buffer */
@@ -3552,15 +3534,7 @@
if( add_bitmap )
alloc_len += msg_len / 8 + ( msg_len % 8 != 0 ); /* Bitmap */
- buf = mbedtls_calloc( 1, alloc_len );
- if( buf == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc failed (%d bytes)", alloc_len ) );
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- }
-
- *target = buf;
- return( 0 );
+ return( alloc_len );
}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
@@ -4516,6 +4490,8 @@
/* Check if the buffering for this seq nr has already commenced. */
if( !hs_buf->is_valid )
{
+ size_t reassembly_buf_sz;
+
hs_buf->is_fragmented =
( ssl_hs_is_proper_fragment( ssl ) == 1 );
@@ -4530,11 +4506,10 @@
goto exit;
}
- ret = ssl_prepare_reassembly_buffer( ssl, msg_len,
- hs_buf->is_fragmented,
- &hs_buf->data );
- if( ret == MBEDTLS_ERR_SSL_ALLOC_FAILED &&
- recv_msg_seq_offset > 0 )
+ reassembly_buf_sz = ssl_get_reassembly_buffer_size( msg_len,
+ hs_buf->is_fragmented );
+ hs_buf->data = mbedtls_calloc( 1, reassembly_buf_sz );
+ if( hs_buf->data == NULL )
{
/* If we run out of RAM trying to buffer a *future*
* message, simply ignore instead of failing. */