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>
This commit is contained in:
parent
6497b5a1d1
commit
da0913ba6b
8 changed files with 36 additions and 1 deletions
|
@ -607,6 +607,9 @@ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx,
|
||||||
if( ( f = fopen( path, "wb" ) ) == NULL )
|
if( ( f = fopen( path, "wb" ) ) == NULL )
|
||||||
return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
|
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,
|
if( ( ret = mbedtls_ctr_drbg_random( ctx, buf,
|
||||||
MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 )
|
MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -640,6 +643,9 @@ int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx,
|
||||||
if( ( f = fopen( path, "rb" ) ) == NULL )
|
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||||
return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
|
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 );
|
n = fread( buf, 1, sizeof( buf ), f );
|
||||||
if( fread( &c, 1, 1, f ) != 0 )
|
if( fread( &c, 1, 1, f ) != 0 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -620,6 +620,7 @@ static int load_file( const char *path, unsigned char **buf, size_t *n )
|
||||||
|
|
||||||
if( ( f = fopen( path, "rb" ) ) == NULL )
|
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||||
return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
|
return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
|
||||||
|
/* The data loaded here is public, so don't bother disabling buffering. */
|
||||||
|
|
||||||
fseek( f, 0, SEEK_END );
|
fseek( f, 0, SEEK_END );
|
||||||
if( ( size = ftell( f ) ) == -1 )
|
if( ( size = ftell( f ) ) == -1 )
|
||||||
|
|
|
@ -457,6 +457,9 @@ int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *p
|
||||||
goto exit;
|
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 )
|
if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) != MBEDTLS_ENTROPY_BLOCK_SIZE )
|
||||||
{
|
{
|
||||||
ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
|
ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
|
||||||
|
@ -484,6 +487,9 @@ int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *
|
||||||
if( ( f = fopen( path, "rb" ) ) == NULL )
|
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||||
return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
|
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 );
|
fseek( f, 0, SEEK_END );
|
||||||
n = (size_t) ftell( f );
|
n = (size_t) ftell( f );
|
||||||
fseek( f, 0, SEEK_SET );
|
fseek( f, 0, SEEK_SET );
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#if defined(MBEDTLS_TIMING_C)
|
#if defined(MBEDTLS_TIMING_C)
|
||||||
#include "mbedtls/timing.h"
|
#include "mbedtls/timing.h"
|
||||||
#endif
|
#endif
|
||||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
#if defined(MBEDTLS_ENTROPY_NV_SEED) || !defined(HAVE_SYSCTL_ARND)
|
||||||
#include "mbedtls/platform.h"
|
#include "mbedtls/platform.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -195,6 +195,9 @@ int mbedtls_platform_entropy_poll( void *data,
|
||||||
if( file == NULL )
|
if( file == NULL )
|
||||||
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
|
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 );
|
read_len = fread( output, 1, len, file );
|
||||||
if( read_len != len )
|
if( read_len != len )
|
||||||
{
|
{
|
||||||
|
|
|
@ -436,6 +436,9 @@ int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const cha
|
||||||
if( ( f = fopen( path, "wb" ) ) == NULL )
|
if( ( f = fopen( path, "wb" ) ) == NULL )
|
||||||
return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
|
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 )
|
if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
@ -465,6 +468,9 @@ int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const ch
|
||||||
if( ( f = fopen( path, "rb" ) ) == NULL )
|
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||||
return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
|
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 );
|
n = fread( buf, 1, sizeof( buf ), f );
|
||||||
if( fread( &c, 1, 1, f ) != 0 )
|
if( fread( &c, 1, 1, f ) != 0 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -605,6 +605,9 @@ int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigne
|
||||||
if( ( f = fopen( path, "rb" ) ) == NULL )
|
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||||
return( MBEDTLS_ERR_MD_FILE_IO_ERROR );
|
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 );
|
mbedtls_md_init( &ctx );
|
||||||
|
|
||||||
if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
|
if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
|
||||||
|
|
|
@ -82,6 +82,9 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n )
|
||||||
if( ( f = fopen( path, "rb" ) ) == NULL )
|
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||||
return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
|
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 );
|
fseek( f, 0, SEEK_END );
|
||||||
if( ( size = ftell( f ) ) == -1 )
|
if( ( size = ftell( f ) ) == -1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -102,6 +102,9 @@ static psa_status_t psa_its_read_file( psa_storage_uid_t uid,
|
||||||
if( *p_stream == NULL )
|
if( *p_stream == NULL )
|
||||||
return( PSA_ERROR_DOES_NOT_EXIST );
|
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 );
|
n = fread( &header, 1, sizeof( header ), *p_stream );
|
||||||
if( n != sizeof( header ) )
|
if( n != sizeof( header ) )
|
||||||
return( PSA_ERROR_DATA_CORRUPT );
|
return( PSA_ERROR_DATA_CORRUPT );
|
||||||
|
@ -201,9 +204,13 @@ psa_status_t psa_its_set( psa_storage_uid_t uid,
|
||||||
|
|
||||||
psa_its_fill_filename( uid, filename );
|
psa_its_fill_filename( uid, filename );
|
||||||
stream = fopen( PSA_ITS_STORAGE_TEMP, "wb" );
|
stream = fopen( PSA_ITS_STORAGE_TEMP, "wb" );
|
||||||
|
|
||||||
if( stream == NULL )
|
if( stream == NULL )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
/* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
|
||||||
|
mbedtls_setbuf( stream, NULL );
|
||||||
|
|
||||||
status = PSA_ERROR_INSUFFICIENT_STORAGE;
|
status = PSA_ERROR_INSUFFICIENT_STORAGE;
|
||||||
n = fwrite( &header, 1, sizeof( header ), stream );
|
n = fwrite( &header, 1, sizeof( header ), stream );
|
||||||
if( n != sizeof( header ) )
|
if( n != sizeof( header ) )
|
||||||
|
|
Loading…
Reference in a new issue