Fix len miscalculation in buffer-based allocator
diff --git a/ChangeLog b/ChangeLog
index a1e9837..85b5652 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -18,6 +18,9 @@
Bugfix
* Stack buffer overflow if ctr_drbg_update() is called with too large
add_len (found by Jean-Philippe Aumasson) (not triggerable remotely).
+ * Possible buffer overflow of length at most POLARSSL_MEMORY_ALIGN_MULTIPLE
+ if memory_buffer_alloc_init() was called with buf not aligned and len not
+ a multiple of POLARSSL_MEMORY_ALIGN_MULTIPLE.
= PolarSSL 1.3.9 released 2014-10-20
Security
diff --git a/library/memory_buffer_alloc.c b/library/memory_buffer_alloc.c
index 9cae251..4a5be47 100644
--- a/library/memory_buffer_alloc.c
+++ b/library/memory_buffer_alloc.c
@@ -563,9 +563,11 @@
if( (size_t) buf % POLARSSL_MEMORY_ALIGN_MULTIPLE )
{
+ /* Adjust len first since buf is used in the computation */
+ len -= POLARSSL_MEMORY_ALIGN_MULTIPLE
+ - (size_t) buf % POLARSSL_MEMORY_ALIGN_MULTIPLE;
buf += POLARSSL_MEMORY_ALIGN_MULTIPLE
- (size_t) buf % POLARSSL_MEMORY_ALIGN_MULTIPLE;
- len -= (size_t) buf % POLARSSL_MEMORY_ALIGN_MULTIPLE;
}
heap.buf = buf;
@@ -623,9 +625,9 @@
int memory_buffer_alloc_self_test( int verbose )
{
- int ret = 0;
unsigned char buf[1024];
- unsigned char *p, *q, *r;
+ unsigned char *p, *q, *r, *end;
+ int ret = 0;
if( verbose != 0 )
polarssl_printf( " MBA test #1 (basic alloc-free cycle): " );
@@ -646,6 +648,9 @@
TEST_ASSERT( check_all_free( ) == 0 );
+ /* Memorize end to compare with the next test */
+ end = heap.buf + heap.len;
+
memory_buffer_alloc_free( );
if( verbose != 0 )
@@ -656,6 +661,8 @@
memory_buffer_alloc_init( buf + 1, sizeof( buf ) - 1 );
+ TEST_ASSERT( heap.buf + heap.len == end );
+
p = polarssl_malloc( 1 );
q = polarssl_malloc( 128 );
r = polarssl_malloc( 16 );