Add memory_buffer_alloc_self_test()
diff --git a/include/polarssl/memory_buffer_alloc.h b/include/polarssl/memory_buffer_alloc.h
index c449752..a1b4937 100644
--- a/include/polarssl/memory_buffer_alloc.h
+++ b/include/polarssl/memory_buffer_alloc.h
@@ -115,6 +115,15 @@
  */
 int memory_buffer_alloc_verify( void );
 
+#if defined(POLARSSL_SELF_TEST)
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if a test failed
+ */
+int memory_buffer_alloc_self_test( int verbose );
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/library/memory_buffer_alloc.c b/library/memory_buffer_alloc.c
index 00ac3f1..4f96018 100644
--- a/library/memory_buffer_alloc.c
+++ b/library/memory_buffer_alloc.c
@@ -586,4 +586,130 @@
     polarssl_zeroize( &heap, sizeof(buffer_alloc_ctx) );
 }
 
+#if defined(POLARSSL_SELF_TEST)
+static int check_pointer( void *p )
+{
+    if( p == NULL )
+        return( -1 );
+
+    if( (size_t) p % POLARSSL_MEMORY_ALIGN_MULTIPLE != 0 )
+        return( -1 );
+
+    return( 0 );
+}
+
+static int check_all_free( )
+{
+    if( heap.current_alloc_size != 0 ||
+        heap.first != heap.first_free ||
+        (void *) heap.first != (void *) heap.buf )
+    {
+        return( -1 );
+    }
+
+    return( 0 );
+}
+
+#define TEST_ASSERT( condition )            \
+    if( ! (condition) )                     \
+    {                                       \
+        if( verbose != 0 )                  \
+            polarssl_printf( "failed\n" );  \
+                                            \
+        ret = 1;                            \
+        goto cleanup;                       \
+    }
+
+int memory_buffer_alloc_self_test( int verbose )
+{
+    int ret = 0;
+    unsigned char buf[1024];
+    unsigned char *p, *q, *r;
+
+    if( verbose != 0 )
+        polarssl_printf( "  MBA test #1 (basic alloc-free cycle): " );
+
+    memory_buffer_alloc_init( buf, sizeof( buf ) );
+
+    p = polarssl_malloc( 1 );
+    q = polarssl_malloc( 128 );
+    r = polarssl_malloc( 16 );
+
+    TEST_ASSERT( check_pointer( p ) == 0 &&
+                 check_pointer( q ) == 0 &&
+                 check_pointer( r ) == 0 );
+
+    polarssl_free( r );
+    polarssl_free( q );
+    polarssl_free( p );
+
+    TEST_ASSERT( check_all_free( ) == 0 );
+
+    memory_buffer_alloc_free( );
+
+    if( verbose != 0 )
+        polarssl_printf( "passed\n" );
+
+    if( verbose != 0 )
+        polarssl_printf( "  MBA test #2 (buf not aligned): " );
+
+    memory_buffer_alloc_init( buf + 1, sizeof( buf ) - 1 );
+
+    p = polarssl_malloc( 1 );
+    q = polarssl_malloc( 128 );
+    r = polarssl_malloc( 16 );
+
+    TEST_ASSERT( check_pointer( p ) == 0 &&
+                 check_pointer( q ) == 0 &&
+                 check_pointer( r ) == 0 );
+
+    polarssl_free( r );
+    polarssl_free( q );
+    polarssl_free( p );
+
+    TEST_ASSERT( check_all_free( ) == 0 );
+
+    memory_buffer_alloc_free( );
+
+    if( verbose != 0 )
+        polarssl_printf( "passed\n" );
+
+    if( verbose != 0 )
+        polarssl_printf( "  MBA test #3 (full): " );
+
+    memory_buffer_alloc_init( buf, sizeof( buf ) );
+
+    p = polarssl_malloc( sizeof( buf ) - sizeof( memory_header ) );
+
+    TEST_ASSERT( check_pointer( p ) == 0 );
+    TEST_ASSERT( polarssl_malloc( 1 ) == NULL );
+
+    polarssl_free( p );
+
+    p = polarssl_malloc( sizeof( buf ) - 2 * sizeof( memory_header ) - 16 );
+    q = polarssl_malloc( 16 );
+
+    TEST_ASSERT( check_pointer( p ) == 0 && check_pointer( q ) == 0 );
+    TEST_ASSERT( polarssl_malloc( 1 ) == NULL );
+
+    polarssl_free( q );
+
+    TEST_ASSERT( polarssl_malloc( 17 ) == NULL );
+
+    polarssl_free( p );
+
+    TEST_ASSERT( check_all_free( ) == 0 );
+
+    memory_buffer_alloc_free( );
+
+    if( verbose != 0 )
+        polarssl_printf( "passed\n" );
+
+cleanup:
+    memory_buffer_alloc_free( );
+
+    return( ret );
+}
+#endif /* POLARSSL_SELF_TEST */
+
 #endif /* POLARSSL_MEMORY_BUFFER_ALLOC_C */
diff --git a/programs/test/selftest.c b/programs/test/selftest.c
index edf3d52..3e68e36 100644
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -226,16 +226,23 @@
 #if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) && defined(POLARSSL_MEMORY_DEBUG)
         memory_buffer_alloc_status();
 #endif
+    }
 
+#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
+    memory_buffer_alloc_free();
+
+    if( ( ret = memory_buffer_alloc_self_test( v ) ) != 0 )
+        return( ret );
+#endif
+
+    if( v != 0 )
+    {
         printf( "  [ All tests passed ]\n\n" );
 #if defined(_WIN32)
         printf( "  Press Enter to exit this program.\n" );
         fflush( stdout ); getchar();
 #endif
     }
-#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
-    memory_buffer_alloc_free();
-#endif
 
     return( ret );
 }