Package: libblockdev3
Version: 3.0.2-1
Severity: normal
Tags: upstream

Dear Maintainer,

libblockdev seems to leak empty temporary directories, when the function 
bd_fs_get_free_space is called (even unsuccessfully) on a btrfs partition as it 
calls fs_mount internally, which then either fails and exhibits the behavior OR 
succeeds and btrfs_get_info leaks the directory.
I am relatively sure that this is not limited to btrfs, but that is what I have 
here.
I noticed this while steam was running and my /tmp directory was suddenly 
overflowing with hundreds of blockdev.XXXXXX directories. I don't know what 
steam does there or if it is in fact steam itself, proton or something else, 
but libblockdev should not leak the directories.

This little piece of code demonstrates the problem. It does not matter, if the 
device exists or not. It just cannot be mounted already.
Run it and an empty blockdev.XXXXXX dir remains in /tmp

#include <blockdev/blockdev.h>
#include <blockdev/fs/generic.h>
#include <stdio.h>

int main()
{
        GError *err = NULL;
        BDPluginSpec fs_plugin = {BD_PLUGIN_FS, NULL};
        BDPluginSpec *plugins[] = {&fs_plugin, NULL};
        if (!bd_init(plugins, NULL, &err)) {
                fprintf(stdout, "failed to init lib: %s\n", err->message);
        }
        err = NULL;
        guint64 space = bd_fs_get_free_space("/dev/sda1", "btrfs", &err);
        if (space == 0) {
                fprintf(stdout, "failed to get fs size: %s\n", err->message);
        } else {
                fprintf(stdout, "%d\n", space);
        }

        return 0;
}

As far as I can see, the following patch should remedy at least the unsuccessul 
path, where the device cannot be mounted. However, I have not tested this!!

diff --git a/src/plugins/fs/generic.c b/src/plugins/fs/generic.c
index 21032b8a..843de8b1 100644
--- a/src/plugins/fs/generic.c
+++ b/src/plugins/fs/generic.c
@@ -650,6 +650,7 @@ static gchar* fs_mount (const gchar *device, gchar *fstype, 
gboolean read_only,
             if (!ret) {
                 g_propagate_prefixed_error (error, l_error, "Failed to mount '%s': 
", device);
                 g_free (mountpoint);
+                g_rmdir (tempdir);
                 return NULL;
             } else
                 *unmount = TRUE;

I am not sure how to handle the successful calls to fs_mount from the other 
functions in that file. Do we really need to delete the dir downstream in all 
the calling functions? Seems strange to me, but I don't see a different 
solution right now.

Ps:
fs_mount() might also leak a little memory in case it creates the tmp mount, 
but I am not certain enough about the behavior of glib2 here (i.e. valgrind 
does not immediately see this as a definite leak). reassigning 'mountpoint' 
with the result of g_mkdtemp() looks as if the original memory, returned by 
g_build_path() is lost? The glib documentation at least suggests a leak here.

from line 642ff:
            mountpoint = g_build_path (G_DIR_SEPARATOR_S, g_get_tmp_dir (), 
"blockdev.XXXXXX", NULL);
            mountpoint = g_mkdtemp (mountpoint);

Regards
  Andre


-- System Information:
Debian Release: trixie/sid
  APT prefers unstable-debug
  APT policy: (500, 'unstable-debug'), (500, 'unstable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 6.3.0-2-amd64 (SMP w/12 CPU threads; PREEMPT)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en_US
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages libblockdev3 depends on:
ii  libblockdev-utils3  3.0.2-1
ii  libc6               2.37-6
ii  libglib2.0-0        2.76.4-3

libblockdev3 recommends no packages.

libblockdev3 suggests no packages.

-- no debconf information

_______________________________________________
Pkg-utopia-maintainers mailing list
Pkg-utopia-maintainers@alioth-lists.debian.net
https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/pkg-utopia-maintainers

Reply via email to