Package: libfm4
Version: 1.3.2-1+rpt18
Severity: normal
X-Debbugs-Cc: [email protected]

Dear Maintainer,

PCManFM reproducibly terminates with SIGSEGV when I drag a directory and quickly release it over an empty area of the current file-view window.

Dropping at that location is not expected to initiate a file operation. Normally, it should either cancel the drag or leave the directory unchanged.

The crash occurs on Raspberry Pi OS Bookworm running on a Raspberry Pi 5. The relevant upstream versions are:

pcmanfm 1.3.2
libfm 1.3.2

PCManFM is running in the Raspberry Pi desktop configuration as:

/usr/bin/pcmanfm --desktop --profile LXDE-pi

Steps to reproduce:

Open a directory in PCManFM containing at least one subdirectory.
Start dragging the subdirectory.
Quickly release the mouse button over empty space in the same file-view window, rather than over another directory or another valid drop target.
PCManFM terminates with SIGSEGV.

The issue is timing-sensitive, but I can reproduce it by performing the drag and release quickly in less than 0.5 seconds.

Expected result:

The drag operation should be ignored or cancelled. PCManFM should remain running, and no file operation should take place.

Actual result:

PCManFM crashes with SIGSEGV.

I ran PCManFM under GDB with the available debug symbols. The immediate cause is that fm_path_list_new_from_uris() receives a NULL uris argument and dereferences it in its loop condition:

Thread 1 "pcmanfm" received signal SIGSEGV, Segmentation fault.
fm_path_list_new_from_uris (uris=0x0) at base/fm-path.c:1508
1508        for(uri = uris; *uri; ++uri)

Relevant backtrace:

#0  fm_path_list_new_from_uris (uris=0x0)
    at base/fm-path.c:1508
#1  0x00007ffff7c2a5f0 in ()
    at /lib/aarch64-linux-gnu/libfm-gtk3.so.4
#2  0x00007ffff6ca7268 in g_closure_invoke ()
    at /lib/aarch64-linux-gnu/libgobject-2.0.so.0
#3  0x00007ffff6cbb88c in ()
    at /lib/aarch64-linux-gnu/libgobject-2.0.so.0
#4  0x00007ffff6cc1c48 in g_signal_emit_valist ()
    at /lib/aarch64-linux-gnu/libgobject-2.0.so.0
#5  0x00007ffff6cc2074 in g_signal_emit_by_name ()
    at /lib/aarch64-linux-gnu/libgobject-2.0.so.0
#6  0x00007ffff7763fd4 in ()
    at /lib/aarch64-linux-gnu/libgtk-3.so.0
#7  0x00007ffff73f8688 in ()
    at /lib/aarch64-linux-gnu/libgtk-3.so.0
#8  0x00007ffff6ca74a0 in ()
    at /lib/aarch64-linux-gnu/libgobject-2.0.so.0
#9  0x00007ffff6cc1c18 in g_signal_emit_valist ()
    at /lib/aarch64-linux-gnu/libgobject-2.0.so.0
#10 0x00007ffff6cc2074 in g_signal_emit_by_name ()
    at /lib/aarch64-linux-gnu/libgobject-2.0.so.0
#11 0x00007ffff7638408 in ()
    at /lib/aarch64-linux-gnu/libgtk-3.so.0
#12 0x00007ffff73f2ac4 in ()
    at /lib/aarch64-linux-gnu/libgtk-3.so.0
#13 0x00007ffff6ca57bc in ()
    at /lib/aarch64-linux-gnu/libgobject-2.0.so.0
#14 0x00007ffff6ca74a0 in ()
    at /lib/aarch64-linux-gnu/libgobject-2.0.so.0
#15 0x00007ffff6cc11d4 in g_signal_emit_valist ()
    at /lib/aarch64-linux-gnu/libgobject-2.0.so.0
#16 0x00007ffff6cc1e70 in g_signal_emit ()
    at /lib/aarch64-linux-gnu/libgobject-2.0.so.0
#17 0x00007ffff77114b8 in ()
    at /lib/aarch64-linux-gnu/libgtk-3.so.0
#18 0x00007ffff759447c in gtk_main_do_event ()
    at /lib/aarch64-linux-gnu/libgtk-3.so.0
#19 0x00007ffff726f218 in ()
    at /lib/aarch64-linux-gnu/libgdk-3.so.0
#20 0x00007ffff72a9bdc in ()
    at /lib/aarch64-linux-gnu/libgdk-3.so.0
#21 0x00007ffff7d36cb4 in g_main_context_dispatch ()
    at /lib/aarch64-linux-gnu/libglib-2.0.so.0
#22 0x00007ffff7d36f58 in ()
    at /lib/aarch64-linux-gnu/libglib-2.0.so.0
#23 0x00007ffff7d37284 in g_main_loop_run ()
    at /lib/aarch64-linux-gnu/libglib-2.0.so.0
#24 0x00007ffff7593584 in gtk_main ()
    at /lib/aarch64-linux-gnu/libgtk-3.so.0
#25 0x0000555555565570 in main (...)
    at ./src/pcmanfm.c:268

At the point of failure:

(gdb) p uris
$1 = (char * const *) 0x0

The corresponding function is:

FmPathList* fm_path_list_new_from_uris(char* const* uris)
{
    char* const* uri;
    FmPathList* pl = fm_path_list_new();
    for(uri = uris; *uri; ++uri)
    {
        ...
    }
}

This suggests that the drag-and-drop data-received path can call
fm_path_list_new_from_uris() after URI extraction has returned NULL. Either the caller should reject NULL URI data, or fm_path_list_new_from_uris() should handle a NULL argument safely.

I inspected libfm 1.4.0 and the current upstream source. The same call sequence appears to remain present, so this does not appear to have an explicit NULL check in the newer upstream version. I have not yet tested the runtime behaviour with libfm 1.4.x.

Please let me know if a complete GDB transcript, package information, or any additional reproduction details would be useful.

Regards,
Yohei Shimmyo


-- System Information:
Debian Release: 12.10
  APT prefers oldstable-updates
APT policy: (500, 'oldstable-updates'), (500, 'oldstable-security'), (500, 'oldstable')
Architecture: arm64 (aarch64)
Foreign Architectures: armhf

Kernel: Linux 6.12.25+rpt-rpi-2712 (SMP w/4 CPU threads; PREEMPT)
Locale: LANG=ja_JP.UTF-8, LC_CTYPE=ja_JP.UTF-8 (charmap=UTF-8) (ignored: LC_ALL set to ja_JP.UTF-8), LANGUAGE=ja_JP.UTF-8
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages libfm4 depends on:
ii  libc6             2.36-9+rpt2+deb12u10
ii  libdbus-glib-1-2  0.112-3
ii  libexif12         0.6.24-1+b1
ii  libfm-data        1.3.2-1+rpt18
ii  libglib2.0-0      2.74.6-2+deb12u9
ii  libmenu-cache3    1.1.0-1.1
ii  lxmenu-data       0.1.5-2.1

Versions of packages libfm4 recommends:
ii  libfm-modules  1.3.2-1+rpt18

libfm4 suggests no packages.

-- no debconf information

Reply via email to