Call setbuf when reading or writing files: library
After opening a file containing sensitive data, call mbedtls_setbuf() to
disable buffering. This way, we don't expose sensitive data to a memory
disclosure vulnerability in a buffer outside our control.
This commit adds a call to mbedtls_setbuf() after each call to fopen(),
except:
* In ctr_drbg.c, in load_file(), because this is only used for DH parameters
and they are not confidential data.
* In psa_its_file.c, in psa_its_remove(), because the file is only opened
to check its existence, we don't read data from it.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c
index 93a7cdc..a2f55cc 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -607,6 +607,9 @@
if( ( f = fopen( path, "wb" ) ) == NULL )
return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
+ /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
+ mbedtls_setbuf( f, NULL );
+
if( ( ret = mbedtls_ctr_drbg_random( ctx, buf,
MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 )
goto exit;
@@ -640,6 +643,9 @@
if( ( f = fopen( path, "rb" ) ) == NULL )
return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
+ /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
+ mbedtls_setbuf( f, NULL );
+
n = fread( buf, 1, sizeof( buf ), f );
if( fread( &c, 1, 1, f ) != 0 )
{
diff --git a/library/dhm.c b/library/dhm.c
index 2ce0ed4..1e95bda 100644
--- a/library/dhm.c
+++ b/library/dhm.c
@@ -620,6 +620,7 @@
if( ( f = fopen( path, "rb" ) ) == NULL )
return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
+ /* The data loaded here is public, so don't bother disabling buffering. */
fseek( f, 0, SEEK_END );
if( ( size = ftell( f ) ) == -1 )
diff --git a/library/entropy.c b/library/entropy.c
index 9e31f84..08c5bd7 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -457,6 +457,9 @@
goto exit;
}
+ /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
+ mbedtls_setbuf( f, NULL );
+
if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) != MBEDTLS_ENTROPY_BLOCK_SIZE )
{
ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
@@ -484,6 +487,9 @@
if( ( f = fopen( path, "rb" ) ) == NULL )
return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
+ /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
+ mbedtls_setbuf( f, NULL );
+
fseek( f, 0, SEEK_END );
n = (size_t) ftell( f );
fseek( f, 0, SEEK_SET );
diff --git a/library/entropy_poll.c b/library/entropy_poll.c
index 058c307..2ae57fd 100644
--- a/library/entropy_poll.c
+++ b/library/entropy_poll.c
@@ -35,7 +35,7 @@
#if defined(MBEDTLS_TIMING_C)
#include "mbedtls/timing.h"
#endif
-#if defined(MBEDTLS_ENTROPY_NV_SEED)
+#if defined(MBEDTLS_ENTROPY_NV_SEED) || !defined(HAVE_SYSCTL_ARND)
#include "mbedtls/platform.h"
#endif
@@ -195,6 +195,9 @@
if( file == NULL )
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+ /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
+ mbedtls_setbuf( file, NULL );
+
read_len = fread( output, 1, len, file );
if( read_len != len )
{
diff --git a/library/hmac_drbg.c b/library/hmac_drbg.c
index ab353bf..8b13a86 100644
--- a/library/hmac_drbg.c
+++ b/library/hmac_drbg.c
@@ -436,6 +436,9 @@
if( ( f = fopen( path, "wb" ) ) == NULL )
return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
+ /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
+ mbedtls_setbuf( f, NULL );
+
if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
goto exit;
@@ -465,6 +468,9 @@
if( ( f = fopen( path, "rb" ) ) == NULL )
return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
+ /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
+ mbedtls_setbuf( f, NULL );
+
n = fread( buf, 1, sizeof( buf ), f );
if( fread( &c, 1, 1, f ) != 0 )
{
diff --git a/library/md.c b/library/md.c
index f2c1a90..a387da5 100644
--- a/library/md.c
+++ b/library/md.c
@@ -605,6 +605,9 @@
if( ( f = fopen( path, "rb" ) ) == NULL )
return( MBEDTLS_ERR_MD_FILE_IO_ERROR );
+ /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
+ mbedtls_setbuf( f, NULL );
+
mbedtls_md_init( &ctx );
if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
diff --git a/library/pkparse.c b/library/pkparse.c
index 22dab3a..0e5dd55 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -82,6 +82,9 @@
if( ( f = fopen( path, "rb" ) ) == NULL )
return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
+ /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
+ mbedtls_setbuf( f, NULL );
+
fseek( f, 0, SEEK_END );
if( ( size = ftell( f ) ) == -1 )
{
diff --git a/library/psa_its_file.c b/library/psa_its_file.c
index f058720..b7c2e6b 100644
--- a/library/psa_its_file.c
+++ b/library/psa_its_file.c
@@ -102,6 +102,9 @@
if( *p_stream == NULL )
return( PSA_ERROR_DOES_NOT_EXIST );
+ /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
+ mbedtls_setbuf( *p_stream, NULL );
+
n = fread( &header, 1, sizeof( header ), *p_stream );
if( n != sizeof( header ) )
return( PSA_ERROR_DATA_CORRUPT );
@@ -201,9 +204,13 @@
psa_its_fill_filename( uid, filename );
stream = fopen( PSA_ITS_STORAGE_TEMP, "wb" );
+
if( stream == NULL )
goto exit;
+ /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
+ mbedtls_setbuf( stream, NULL );
+
status = PSA_ERROR_INSUFFICIENT_STORAGE;
n = fwrite( &header, 1, sizeof( header ), stream );
if( n != sizeof( header ) )