[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