[PATCH] imfs: Fix index underrun when extending empty file
Christian MAUDERER
christian.mauderer at embedded-brains.de
Mon Apr 4 14:28:30 UTC 2022
Please note: I would like to apply this to the 5 branch too. I created a
ticket for 5 here:
https://devel.rtems.org/ticket/4638
Note that both tickets (5 and 6) are clones of an old 4.11 ticket:
https://devel.rtems.org/ticket/2353
I didn't plan to backport the patch to 4.11. I'll add a comment to the
ticket that the problem is fixed in 5 and 6. Should I close the 4.11
ticket with a "wontfix" or just let it open?
Best regards
Christian
Am 04.04.22 um 16:23 schrieb Christian Mauderer:
> Currently the following sequence causes a endless loop when extending an
> IMFS file:
>
> - Create a file with zero length and close it.
> - Make sure nearly no allocatable memory is left.
> - Open the file and write enough data into it that more than the
> remaining memory will be used.
>
> In that case when extending the IMFS file, the file currently need zero
> blocks. If allocating enough new blocks fails, the already allocated new
> blocks will be freed again.
>
> The comparison of block>=old_blocks that has been used prior to this
> patch compared two unsigned numbers. If old_blocks was zero, the
> comparison of these two numbers always evaluated to true.
>
> This patch frees the last block in a separate step to avoid this
> problem.
>
> Fixes #4639
> ---
> cpukit/libfs/src/imfs/imfs_memfile.c | 3 ++-
> testsuites/psxtests/psximfs02/init.c | 30 +++++++++++++++++++++++++++-
> 2 files changed, 31 insertions(+), 2 deletions(-)
>
> diff --git a/cpukit/libfs/src/imfs/imfs_memfile.c b/cpukit/libfs/src/imfs/imfs_memfile.c
> index 23c7192717..769a570ecf 100644
> --- a/cpukit/libfs/src/imfs/imfs_memfile.c
> +++ b/cpukit/libfs/src/imfs/imfs_memfile.c
> @@ -208,9 +208,10 @@ static int IMFS_memfile_extend(
> offset = 0;
> }
> } else {
> - for ( ; block>=old_blocks ; block-- ) {
> + for ( ; block>old_blocks ; block-- ) {
> IMFS_memfile_remove_block( memfile, block );
> }
> + IMFS_memfile_remove_block( memfile, old_blocks );
> rtems_set_errno_and_return_minus_one( ENOSPC );
> }
> }
> diff --git a/testsuites/psxtests/psximfs02/init.c b/testsuites/psxtests/psximfs02/init.c
> index 15b9137121..04f806f565 100644
> --- a/testsuites/psxtests/psximfs02/init.c
> +++ b/testsuites/psxtests/psximfs02/init.c
> @@ -23,6 +23,8 @@
> #include <rtems/malloc.h>
> #include <rtems/libcsupport.h>
>
> +#define MEMFILE_BYTES_PER_BLOCK 16
> +
> const char rtems_test_name[] = "PSXIMFS 2";
>
> /* forward declarations to avoid warnings */
> @@ -43,12 +45,17 @@ rtems_task Init(
> static const uintptr_t slink_2_name_size [] = {
> sizeof( slink_2_name )
> };
> + static const uintptr_t some_blocks [] = {
> + MEMFILE_BYTES_PER_BLOCK * 10
> + };
> + static const char some_data[MEMFILE_BYTES_PER_BLOCK * 11];
>
> int status = 0;
> void *opaque;
> char linkname_n[32] = {0};
> char linkname_p[32] = {0};
> int i;
> + int fd;
> struct stat stat_buf;
>
> TEST_BEGIN();
> @@ -102,6 +109,27 @@ rtems_task Init(
> rtems_test_assert( status == -1 );
> rtems_test_assert( errno == EACCES );
>
> + puts( "Allocate most of heap with a little bit left" );
> + opaque = rtems_heap_greedy_allocate( some_blocks, 1 );
> +
> + puts( "Create an empty file.");
> + status = mknod( "/foo", S_IFREG | S_IRWXU, 0LL );
> + rtems_test_assert( status == 0 );
> +
> + puts( "Then increase it's size to more than remaining space" );
> + fd = open( "/foo", O_WRONLY | O_TRUNC);
> + rtems_test_assert( fd >= 0 );
> + status = write(fd, some_data, sizeof(some_data));
> + rtems_test_assert( status == -1);
> + rtems_test_assert( errno == ENOSPC );
> +
> + puts( "Clean up again" );
> + status = close(fd);
> + rtems_test_assert( status == 0);
> + status = remove( "/foo" );
> + rtems_test_assert( status == 0);
> + rtems_heap_greedy_free( opaque );
> +
> puts( "Allocate most of heap" );
> opaque = rtems_heap_greedy_allocate( mount_table_entry_size, 1 );
>
> @@ -202,7 +230,7 @@ rtems_task Init(
> #define CONFIGURE_FILESYSTEM_IMFS
>
> #define CONFIGURE_MAXIMUM_TASKS 1
> -#define CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK 16
> +#define CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK MEMFILE_BYTES_PER_BLOCK
> #define CONFIGURE_IMFS_ENABLE_MKFIFO
> #define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 4
> #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
--
--------------------------------------------
embedded brains GmbH
Herr Christian MAUDERER
Dornierstr. 4
82178 Puchheim
Germany
email: christian.mauderer at embedded-brains.de
phone: +49-89-18 94 741 - 18
fax: +49-89-18 94 741 - 08
Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/
More information about the devel
mailing list