[PATCH] imfs: Fix index underrun when extending empty file

Joel Sherrill joel at rtems.org
Mon Apr 4 14:40:57 UTC 2022


On Mon, Apr 4, 2022, 9:28 AM Christian MAUDERER <
christian.mauderer at embedded-brains.de> wrote:

> 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?
>

If the ticket applies easily, just apply it after testing on 5 and 6.
Please.

Is there a test case for this?

--joel

>
> 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/
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel


More information about the devel mailing list