segfault at src/frdp-channel-clipboard.c:784
When using gnome-connections to use a second machine via RDP, the program may crash when following the reproduction steps outlined below. When this crash occurs, GDB points to a segfault triggered by frdp-channel-clipboard.c:784 having an invalid value for priv->cliprdr_client_context
. Additional debugging shows that this pointer is stale and points to a previously-freed instance. When compiling with ASAN enabled the process crashes earlier, at the very first use-after-free attempt.
It appears that the FreeRDP library is holding on to the previous connection's FrdpChannelClipboard
object. That object is seemingly not actually freed even though its private data is. When the second connection is made, the old object is used for some clipboard operations, which ends up causing the attempted use-after-free of the private data. I'm not sure where FreeRDP is still holding on to the old object, since frdp-gtk clearly attempts to destroy and create a new one for the connection in frdp-session.c:frdp_on_channel_connected_event_handler
(and from what I can tell, its own pointers are nulled and then pointed to the new FrdpChannelClipboard
object).
Reproduction Steps
- Connect to a remote server
- Copy some text on the remote server and paste it on the remote server.
- Disconnect
- Re-connect to the previous server
- Crash occurs immediately after this second connection is made
System Information
- Distro: Arch Linux
- Desktop: GNOME 45.3
- Windowing System: xorg-server 21.1.11-1
-
Software: gnome-connections-45.0-1
- gtk-frdp @ 62fc62c5, plus !27 (merged) to fix initial connect issue
GDB Session
Thread 39 "pool" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffc2ffd6c0 (LWP 207891)]
send_data_request (self=0x7fffd0f4e7b0, format_id=13) at ../gnome-connections-45.0/subprojects/gtk-frdp/src/frdp-channel-clipboard.c:784
Downloading source file /usr/src/debug/gnome-connections/build/../gnome-connections-45.0/subprojects/gtk-frdp/src/frdp-channel-clipboard.c
784 ../gnome-connections-45.0/subprojects/gtk-frdp/src/frdp-channel-clipboard.c: Directory not empty.
(gdb) bt
#0 send_data_request (self=0x7fffd0f4e7b0, format_id=13) at ../gnome-connections-45.0/subprojects/gtk-frdp/src/frdp-channel-clipboard.c:784
#1 0x00007ffff7fba3b9 in frdp_clipboard_request_send (self=0x7fffd0f4e7b0, format_id=13) at ../gnome-connections-45.0/subprojects/gtk-frdp/src/frdp-channel-clipboard.c:822
#2 0x00007ffff7fba5ff in _gtk_clipboard_get_func (clipboard=0x5555559ae0e0, selection_data=0x7fffc2ffbd80, info=13, user_data=0x7fffd0f4e7b0) at ../gnome-connections-45.0/subprojects/gtk-frdp/src/frdp-channel-clipboard.c:895
#3 0x00007ffff7288ce8 in () at /usr/lib/libgtk-3.so.0
#4 0x00007ffff7c75b73 in () at /usr/lib/libgobject-2.0.so.0
#5 0x00007ffff7c75f50 in g_signal_emit_by_name () at /usr/lib/libgobject-2.0.so.0
#6 0x00007ffff747cdac in () at /usr/lib/libgtk-3.so.0
#7 0x00007ffff74827b5 in gtk_selection_convert () at /usr/lib/libgtk-3.so.0
#8 0x00007ffff7fbc3f8 in server_format_data_request (context=0x7fffd0e84250, format_data_request=0x7fffc2ffbf10) at ../gnome-connections-45.0/subprojects/gtk-frdp/src/frdp-channel-clipboard.c:1396
#9 0x00007ffff6896ae9 in cliprdr_process_format_data_request (msgFlags=<optimized out>, dataLen=<optimized out>, s=0x5555557fce90, cliprdr=0x7fffd0e86f60)
at /usr/src/debug/freerdp/FreeRDP-2.11.4/channels/cliprdr/client/cliprdr_format.c:136
#10 cliprdr_order_recv (s=0x5555557fce90, cliprdr=<optimized out>) at /usr/src/debug/freerdp/FreeRDP-2.11.4/channels/cliprdr/client/cliprdr_main.c:499
#11 cliprdr_virtual_channel_client_thread (arg=0x7fffd0e86f60) at /usr/src/debug/freerdp/FreeRDP-2.11.4/channels/cliprdr/client/cliprdr_main.c:981
#12 0x00007ffff6b2fc80 in thread_launcher (arg=0x7fffd040ef70) at /usr/src/debug/freerdp/FreeRDP-2.11.4/winpr/libwinpr/thread/thread.c:530
#13 0x00007ffff6c529eb in start_thread (arg=<optimized out>) at pthread_create.c:444
#14 0x00007ffff6cd67cc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
(gdb) list
warning: Source file is more recent than executable.
779 CLIPRDR_FORMAT_DATA_REQUEST *new_request;
780
781 new_request = g_new0 (CLIPRDR_FORMAT_DATA_REQUEST, 1);
782 new_request->requestedFormatId = format_id;
783
784 return priv->cliprdr_client_context->ClientFormatDataRequest (priv->cliprdr_client_context, new_request);
785 }
786
787 static FrdpClipboardRequest *
788 frdp_clipboard_request_new (guint count)
(gdb) p priv
$1 = (FrdpChannelClipboardPrivate *) 0x7fffd0f4e720
(gdb) p priv->cliprdr_client_context
$2 = (CliprdrClientContext *) 0x5552aa57ebde
(gdb) p *priv->cliprdr_client_context
Cannot access memory at address 0x5552aa57ebde
ASAN Error
==204251==ERROR: AddressSanitizer: heap-use-after-free on address 0x60f000142894 at pc 0x7f57a19ccf43 bp 0x7f57736b5770 sp 0x7f57736b5760
READ of size 4 at 0x60f000142894 thread T38
#0 0x7f57a19ccf42 in frdp_clipboard_request_send ../gnome-connections-45.0/subprojects/gtk-frdp/src/frdp-channel-clipboard.c:808
#1 0x7f57a19cd984 in _gtk_clipboard_get_func ../gnome-connections-45.0/subprojects/gtk-frdp/src/frdp-channel-clipboard.c:895
#2 0x7f57a0688ce7 (/usr/lib/libgtk-3.so.0+0x88ce7) (BuildId: 3db6bdac937fa406619fbf34f7ff2f6406e0bba7)
#3 0x7f57a0ff8b72 (/usr/lib/libgobject-2.0.so.0+0x33b72) (BuildId: d52cf1f005cfe3530046602d6ca3fff01f798d5f)
#4 0x7f57a0ff8f4f in g_signal_emit_by_name (/usr/lib/libgobject-2.0.so.0+0x33f4f) (BuildId: d52cf1f005cfe3530046602d6ca3fff01f798d5f)
#5 0x7f57a087cdab (/usr/lib/libgtk-3.so.0+0x27cdab) (BuildId: 3db6bdac937fa406619fbf34f7ff2f6406e0bba7)
#6 0x7f57a08827b4 in gtk_selection_convert (/usr/lib/libgtk-3.so.0+0x2827b4) (BuildId: 3db6bdac937fa406619fbf34f7ff2f6406e0bba7)
#7 0x7f57a19d2314 in server_format_data_request ../gnome-connections-45.0/subprojects/gtk-frdp/src/frdp-channel-clipboard.c:1396
#8 0x7f579f8d0ae8 (/usr/lib/libfreerdp-client2.so.2+0x3cae8) (BuildId: 8e129be77f5b210ba5c81a6ff36d7b9ae1d56319)
#9 0x7f579fb69c7f (/usr/lib/libwinpr2.so.2+0x6bc7f) (BuildId: 0fd428da165454baf670564881ed518fddb48347)
#10 0x7f579ffaf9ea (/usr/lib/libc.so.6+0x8c9ea) (BuildId: 8bfe03f6bf9b6a6e2591babd0bbc266837d8f658)
#11 0x7f57a00337cb (/usr/lib/libc.so.6+0x1107cb) (BuildId: 8bfe03f6bf9b6a6e2591babd0bbc266837d8f658)
0x60f000142894 is located 84 bytes inside of 168-byte region [0x60f000142840,0x60f0001428e8)
freed by thread T0 here:
#0 0x7f57a12dfdb2 in __interceptor_free /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:52
#1 0x7f57a0ffebd0 in g_type_free_instance (/usr/lib/libgobject-2.0.so.0+0x39bd0) (BuildId: d52cf1f005cfe3530046602d6ca3fff01f798d5f)
previously allocated by thread T10 here:
#0 0x7f57a12e0cc1 in __interceptor_calloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:77
#1 0x7f57a0edd2ba in g_malloc0 (/usr/lib/libglib-2.0.so.0+0x642ba) (BuildId: d310ee36df88b18d95f79813384e6f7decd59c68)
Thread T38 created by T10 here:
#0 0x7f57a124a497 in __interceptor_pthread_create /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_interceptors.cpp:208
#1 0x7f579fb696bb (/usr/lib/libwinpr2.so.2+0x6b6bb) (BuildId: 0fd428da165454baf670564881ed518fddb48347)
#2 0x7f579fb6b343 in CreateThread (/usr/lib/libwinpr2.so.2+0x6d343) (BuildId: 0fd428da165454baf670564881ed518fddb48347)
#3 0x7f579f8cea8e (/usr/lib/libfreerdp-client2.so.2+0x3aa8e) (BuildId: 8e129be77f5b210ba5c81a6ff36d7b9ae1d56319)
#4 0x7f579f9c09ac (/usr/lib/libfreerdp2.so.2+0x779ac) (BuildId: ddee7241e593763f2ac6c1850f6239fca0059160)
#5 0x7f579f9c836d in freerdp_connect (/usr/lib/libfreerdp2.so.2+0x7f36d) (BuildId: ddee7241e593763f2ac6c1850f6239fca0059160)
#6 0x7f57a19c38a4 in frdp_session_connect_thread ../gnome-connections-45.0/subprojects/gtk-frdp/src/frdp-session.c:773
#7 0x7f57a10d4db7 (/usr/lib/libgio-2.0.so.0+0xaddb7) (BuildId: 895d79e5cc47d609ac2f19b0d8174b11176cd967)
Thread T10 created by T1 here:
#0 0x7f57a124a497 in __interceptor_pthread_create /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_interceptors.cpp:208
#1 0x7f57a0f05fb3 (/usr/lib/libglib-2.0.so.0+0x8cfb3) (BuildId: d310ee36df88b18d95f79813384e6f7decd59c68)
Thread T1 created by T0 here:
#0 0x7f57a124a497 in __interceptor_pthread_create /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_interceptors.cpp:208
#1 0x7f57a0f05fb3 (/usr/lib/libglib-2.0.so.0+0x8cfb3) (BuildId: d310ee36df88b18d95f79813384e6f7decd59c68)
SUMMARY: AddressSanitizer: heap-use-after-free ../gnome-connections-45.0/subprojects/gtk-frdp/src/frdp-channel-clipboard.c:808 in frdp_clipboard_request_send
Shadow bytes around the buggy address:
0x60f000142600: fd fd fd fa fa fa fa fa fa fa fa fa fd fd fd fd
0x60f000142680: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x60f000142700: fd fd fa fa fa fa fa fa fa fa fd fd fd fd fd fd
0x60f000142780: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x60f000142800: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
=>0x60f000142880: fd fd[fd]fd fd fd fd fd fd fd fd fd fd fa fa fa
0x60f000142900: fa fa fa fa fa fa 00 00 00 00 00 00 00 00 00 00
0x60f000142980: 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa fa
0x60f000142a00: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 00
0x60f000142a80: 00 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa
0x60f000142b00: fa fa 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==204251==ABORTING