[rtems commit] dosfs: Fix memory leak on failed mounts.

Christian Mauderer christianm at rtems.org
Tue Aug 4 06:27:41 UTC 2020


Module:    rtems
Branch:    5
Commit:    4a2ac5ef8d7e8bac4c63b26420d0df08ce82aa09
Changeset: http://git.rtems.org/rtems/commit/?id=4a2ac5ef8d7e8bac4c63b26420d0df08ce82aa09

Author:    Christian Mauderer <christian.mauderer at embedded-brains.de>
Date:      Mon Aug  3 14:18:33 2020 +0200

dosfs: Fix memory leak on failed mounts.

Currently if mount fails, a converter isn't destroyed. We have to take
care of two cases:

1. The user doesn't provide a converter.

In this case mounting a dosfs creates a default converter. This patch
makes sure that the converter is destroyed again if mount failes for
this case.

2. The user provides a converter.

In this case it's not sure that the dosfs specific routines are reached
because mount can fail before that. Therefore the user has to destroy
the converter himself again. This patch adds a documentation for that
and implements it in the media server.

Closes #4041.

---

 cpukit/include/rtems/dosfs.h        | 7 +++++++
 cpukit/libblock/src/media.c         | 1 +
 cpukit/libfs/src/dosfs/msdos_init.c | 5 +++++
 3 files changed, 13 insertions(+)

diff --git a/cpukit/include/rtems/dosfs.h b/cpukit/include/rtems/dosfs.h
index 7691ed7..70347f0 100644
--- a/cpukit/include/rtems/dosfs.h
+++ b/cpukit/include/rtems/dosfs.h
@@ -214,6 +214,9 @@ typedef struct {
   /**
    * @brief Converter implementation for new file system instance.
    *
+   * Note: If you pass a converter to mount, you have to destroy it yourself if
+   * mount failed. In a good case it is destroyed at unmount.
+   *
    * Before converters have been added to the RTEMS implementation of the FAT
    * file system, the implementation was:
    * - Short names were saved in code page format (as is still the case).
@@ -270,6 +273,10 @@ typedef struct {
    *       RTEMS_FILESYSTEM_READ_WRITE,
    *       &mount_opts
    *     );
+   *
+   *     if (rv != 0) {
+   *       (*mount_opts.converter->handler->destroy)(mount_opts.converter);
+   *     }
    *   } else {
    *     rv = -1;
    *     errno = ENOMEM;
diff --git a/cpukit/libblock/src/media.c b/cpukit/libblock/src/media.c
index 5b2b06b..4fc12e0 100644
--- a/cpukit/libblock/src/media.c
+++ b/cpukit/libblock/src/media.c
@@ -504,6 +504,7 @@ static rtems_status_code mount_worker(
     if (rv != 0) {
       rmdir(mount_path);
       free(mount_path);
+      (*mount_options.converter->handler->destroy)(mount_options.converter);
 
       return RTEMS_IO_ERROR;
     }
diff --git a/cpukit/libfs/src/dosfs/msdos_init.c b/cpukit/libfs/src/dosfs/msdos_init.c
index 3ea6f10..2874172 100644
--- a/cpukit/libfs/src/dosfs/msdos_init.c
+++ b/cpukit/libfs/src/dosfs/msdos_init.c
@@ -103,10 +103,12 @@ int rtems_dosfs_initialize(
     int                                rc = 0;
     const rtems_dosfs_mount_options   *mount_options = data;
     rtems_dosfs_convert_control       *converter;
+    bool                               converter_created = false;
 
 
     if (mount_options == NULL || mount_options->converter == NULL) {
         converter = rtems_dosfs_create_default_converter();
+        converter_created = true;
     } else {
         converter = mount_options->converter;
     }
@@ -117,6 +119,9 @@ int rtems_dosfs_initialize(
                                       &msdos_file_handlers,
                                       &msdos_dir_handlers,
                                       converter);
+        if (rc != 0 && converter_created) {
+            (*converter->handler->destroy)(converter);
+        }
     } else {
         errno = ENOMEM;
         rc = -1;



More information about the vc mailing list