[rtems commit] libblock: Fix sparse disk
Sebastian Huber
sebh at rtems.org
Mon Oct 12 06:23:07 UTC 2020
Module: rtems
Branch: master
Commit: b434dc1874b928eb879f77ac0fb2541659cd4d0b
Changeset: http://git.rtems.org/rtems/commit/?id=b434dc1874b928eb879f77ac0fb2541659cd4d0b
Author: Sebastian Huber <sebastian.huber at embedded-brains.de>
Date: Mon Oct 12 08:09:13 2020 +0200
libblock: Fix sparse disk
The qsort() in sparse_disk_get_new_block() may move the appended key
which invalidates the pointer.
Close #4142.
---
cpukit/libblock/src/sparse-disk.c | 69 ++++++++++++++++++++-------------------
1 file changed, 35 insertions(+), 34 deletions(-)
diff --git a/cpukit/libblock/src/sparse-disk.c b/cpukit/libblock/src/sparse-disk.c
index 58ff8d3..550c834 100644
--- a/cpukit/libblock/src/sparse-disk.c
+++ b/cpukit/libblock/src/sparse-disk.c
@@ -111,22 +111,43 @@ static int sparse_disk_compare( const void *aa, const void *bb )
}
}
+static rtems_sparse_disk_key *sparse_disk_find_block(
+ const rtems_sparse_disk *sparse_disk,
+ rtems_blkdev_bnum block
+)
+{
+ rtems_sparse_disk_key key = { .block = block };
+
+ return bsearch(
+ &key,
+ sparse_disk->key_table,
+ sparse_disk->used_count,
+ sizeof( rtems_sparse_disk_key ),
+ sparse_disk_compare
+ );
+}
+
static rtems_sparse_disk_key *sparse_disk_get_new_block(
rtems_sparse_disk *sparse_disk,
- const rtems_blkdev_bnum block )
+ const rtems_blkdev_bnum block
+)
{
rtems_sparse_disk_key *key;
- if ( sparse_disk->used_count < sparse_disk->blocks_with_buffer ) {
- key = &sparse_disk->key_table[sparse_disk->used_count];
- key->block = block;
- ++sparse_disk->used_count;
- qsort( sparse_disk->key_table, sparse_disk->used_count,
- sizeof( rtems_sparse_disk_key ), sparse_disk_compare );
- } else
+ if ( sparse_disk->used_count >= sparse_disk->blocks_with_buffer ) {
return NULL;
+ }
- return key;
+ key = &sparse_disk->key_table[ sparse_disk->used_count ];
+ key->block = block;
+ ++sparse_disk->used_count;
+ qsort(
+ sparse_disk->key_table,
+ sparse_disk->used_count,
+ sizeof( rtems_sparse_disk_key ),
+ sparse_disk_compare
+ );
+ return sparse_disk_find_block( sparse_disk, block );
}
static int sparse_disk_read_block(
@@ -135,23 +156,13 @@ static int sparse_disk_read_block(
uint8_t *buffer,
const size_t buffer_size )
{
- rtems_sparse_disk_key *key;
- rtems_sparse_disk_key block_key = {
- .block = block,
- .data = NULL
- };
size_t bytes_to_copy = sparse_disk->media_block_size;
+ rtems_sparse_disk_key *key;
if ( buffer_size < bytes_to_copy )
bytes_to_copy = buffer_size;
- key = bsearch(
- &block_key,
- sparse_disk->key_table,
- sparse_disk->used_count,
- sizeof( rtems_sparse_disk_key ),
- sparse_disk_compare
- );
+ key = sparse_disk_find_block( sparse_disk, block );
if ( NULL != key )
memcpy( buffer, key->data, bytes_to_copy );
@@ -167,14 +178,10 @@ static int sparse_disk_write_block(
const uint8_t *buffer,
const size_t buffer_size )
{
- unsigned int i;
+ size_t bytes_to_copy = sparse_disk->media_block_size;
bool block_needs_writing = false;
rtems_sparse_disk_key *key;
- rtems_sparse_disk_key block_key = {
- .block = block,
- .data = NULL
- };
- size_t bytes_to_copy = sparse_disk->media_block_size;
+ size_t i;
if ( buffer_size < bytes_to_copy )
bytes_to_copy = buffer_size;
@@ -183,13 +190,7 @@ static int sparse_disk_write_block(
* If the read method does not find a block it will deliver the fill pattern anyway.
*/
- key = bsearch(
- &block_key,
- sparse_disk->key_table,
- sparse_disk->used_count,
- sizeof( rtems_sparse_disk_key ),
- sparse_disk_compare
- );
+ key = sparse_disk_find_block( sparse_disk, block );
if ( NULL == key ) {
for ( i = 0; ( !block_needs_writing ) && ( i < bytes_to_copy ); ++i ) {
More information about the vc
mailing list