Wireshark-dev: [Wireshark-dev] Crash in RDP/EGFX dissector

From: Cristian Constantin <const.crist@xxxxxxxxxxxxxx>
Date: Fri, 13 Jan 2023 19:34:51 +0100
Hi!

Wireshark crashes while decoding relatively large (~20 MBytes)
captures with RDP traffic.

Here is how the stack trace looks like (only frames 0-26, since there
are 90 frames in the core dump):

(gdb) bt
#0  __memmove_avx_unaligned_erms () at
../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:880
#1  0x00007f3f7b0061c7 in memcpy (__len=74141568, __src=<optimized
out>, __dest=<optimized out>)
    at /usr/include/x86_64-linux-gnu/bits/string_fortified.h:29
#2  zgfx_write_from_history (count=293605376, distance=<optimized
out>, zgfx=0x5638bbfd2060)
    at ./epan/tvbuff_rdp.c:311
#3  rdp8_decompress_segment (zgfx=zgfx@entry=0x5638bbfd2060,
tvb=<optimized out>)
    at ./epan/tvbuff_rdp.c:441
#4  0x00007f3f7b006657 in rdp8_decompress
    (zgfx=0x5638bbfd2060, allocator=0x5638b94b9450,
tvb=tvb@entry=0x5638c20a2d80, offset=1,
    offset@entry=0) at ./epan/tvbuff_rdp.c:478
#5  0x00007f3f7b882cdf in dissect_rdp_egfx
    (tvb=0x5638c20a2d80, pinfo=0x7ffc1d3a9788,
parent_tree=0x7f3f68011470, data=<optimized out>)
    at ./epan/dissectors/packet-rdp_egfx.c:385
#6  0x00007f3f7afb5558 in call_dissector_through_handle
    (handle=handle@entry=0x5638ba6133a0, tvb=tvb@entry=0x5638c20a2d80,
pinfo=pinfo@entry=0x7ffc1d3a9788, tree=tree@entry=0x5638c08eac00,
data=data@entry=0x0) at ./epan/packet.c:757
#7  0x00007f3f7afb642d in call_dissector_work
    (handle=0x5638ba6133a0, tvb=0x5638c20a2d80,
pinfo_arg=0x7ffc1d3a9788, tree=0x5638c08eac00, add_proto_name=1,
data=0x0) at ./epan/packet.c:850
#8  0x00007f3f7afb8887 in call_dissector_with_data
    (handle=<optimized out>, tvb=0x5638c20a2d80, pinfo=0x7ffc1d3a9788,
tree=0x5638c08eac00, data=<optimized out>) at ./epan/packet.c:3283
#9  0x00007f3f7b8822cc in dissect_rdp_drdynvc
    (tvb=0x5638c2013ca0, pinfo=0x7ffc1d3a9788, parent_tree=<optimized
out>, data=<optimized out>)
    at ./epan/dissectors/packet-rdp_drdynvc.c:438
#10 0x00007f3f7afb5558 in call_dissector_through_handle
    (handle=handle@entry=0x5638ba613340, tvb=tvb@entry=0x5638c2013ca0,
pinfo=pinfo@entry=0x7ffc1d3a9788, tree=tree@entry=0x5638c08eab20,
data=data@entry=0x0) at ./epan/packet.c:757
#11 0x00007f3f7afb642d in call_dissector_work
    (handle=0x5638ba613340, tvb=0x5638c2013ca0,
pinfo_arg=0x7ffc1d3a9788, tree=0x5638c08eab20, add_proto_name=1,
data=0x0) at ./epan/packet.c:850
#12 0x00007f3f7afb8887 in call_dissector_with_data
    (handle=<optimized out>, tvb=0x5638c2013ca0, pinfo=0x7ffc1d3a9788,
tree=0x5638c08eab20, data=<optimized out>) at ./epan/packet.c:3283
#13 0x00007f3f7b87ed63 in dissect_rdp_channelPDU
    (tree=0x5638c08eab20, pinfo=<optimized out>, offset=<optimized
out>, tvb=0x5638c1ef3e80)
    at ./epan/dissectors/packet-rdp.c:1399
#14 dissect_rdp_SendData
    (tvb=0x5638c1ef3e80, pinfo=0x7ffc1d3a9788, tree=0x5638c08eab20,
data=<optimized out>)
    at ./epan/dissectors/packet-rdp.c:2162
#15 0x00007f3f7afb5558 in call_dissector_through_handle
    (handle=handle@entry=0x5638bbd83110, tvb=tvb@entry=0x5638c1ef3e80,
pinfo=pinfo@entry=0x7ffc1d3a9788, tree=tree@entry=0x7f3f68011470,
data=data@entry=0x0) at ./epan/packet.c:757
#16 0x00007f3f7afb642d in call_dissector_work
    (handle=0x5638bbd83110, tvb=tvb@entry=0x5638c1ef3e80,
pinfo_arg=pinfo_arg@entry=0x7ffc1d3a9788,
tree=tree@entry=0x7f3f68011470, add_proto_name=add_proto_name@entry=1,
data=data@entry=0x0)
    at ./epan/packet.c:850
#17 0x00007f3f7afb6fc2 in dissector_try_uint_new
    (sub_dissectors=<optimized out>, uint_val=1007,
tvb=0x5638c1ef3e80, pinfo=0x7ffc1d3a9788, tree=0x7f3f68011470,
add_proto_name=add_proto_name@entry=1, data=0x0) at
./epan/packet.c:1450
#18 0x00007f3f7afb7035 in dissector_try_uint
    (sub_dissectors=<optimized out>, uint_val=<optimized out>,
tvb=<optimized out>, pinfo=<optimized out>, tree=<optimized out>) at
./epan/packet.c:1474
#19 0x00007f3f7bfb3bfa in dissect_t124_T_userData_01
    (tvb=<optimized out>, offset=6616, actx=0x7ffc1d3a7920,
tree=<optimized out>, hf_index=<optimized out>) at
./asn1/t124/t124.cnf:187
#20 0x00007f3f7b80b792 in dissect_per_sequence
    (tvb=0x5638c1f76f70, offset=44, actx=0x7ffc1d3a7920,
parent_tree=<optimized out>, hf_index=<optimized out>,
ett_index=<optimized out>, sequence=0x7f3f7decb5a0
<SendDataIndication_sequence>)
    at ./epan/dissectors/packet-per.c:1925
#21 0x00007f3f7bfb2c4c in dissect_t124_SendDataIndication
--Type <RET> for more, q to quit, c to continue without paging--
    (tvb=<optimized out>, offset=<optimized out>, actx=<optimized
out>, tree=<optimized out>, hf_index=<optimized out>) at
./asn1/t124/t124.cnf:208
#22 0x00007f3f7b80b394 in dissect_per_choice
(tvb=tvb@entry=0x5638c1f76f70, offset=6,
    offset@entry=0, actx=actx@entry=0x7ffc1d3a7920,
tree=tree@entry=0x5638c08ea8b0, hf_index=188090, ett_index=49148,
choice=0x7f3f7deca660 <DomainMCSPDU_choice>, value=0x7ffc1d3a791c)
    at ./epan/dissectors/packet-per.c:1768
#23 0x00007f3f7bfb4570 in dissect_t124_DomainMCSPDU
    (offset=0, hf_index=<optimized out>, tree=0x5638c08ea8b0,
actx=0x7ffc1d3a7920, tvb=0x5638c1f76f70)
    at ./asn1/t124/t124.cnf:195
#24 dissect_DomainMCSPDU_PDU
    (tvb=tvb@entry=0x5638c1f76f70, pinfo=pinfo@entry=0x7ffc1d3a9788,
tree=tree@entry=0x5638c08ea8b0)
    at ./asn1/t124/packet-t124-template.c:102
#25 0x00007f3f7bfb4b71 in dissect_t125
    (tvb=tvb@entry=0x5638c1f76f70, pinfo=pinfo@entry=0x7ffc1d3a9788,
parent_tree=parent_tree@entry=0x7f3f68011470, data=data@entry=0x0) at
./asn1/t125/packet-t125-template.c:78
#26 0x00007f3f7bfb4dcc in dissect_t125_heur

Details about frames 2, 3:

(gdb) f 2
#2  zgfx_write_from_history (count=293605376, distance=<optimized
out>, zgfx=0x5638bbfd2060)
    at ./epan/tvbuff_rdp.c:311
311 memcpy(outputPtr, &(zgfx->outputSegment[zgfx->outputCount]), toCopy);
(gdb) f 3
#3  rdp8_decompress_segment (zgfx=zgfx@entry=0x5638bbfd2060,
tvb=<optimized out>)
    at ./epan/tvbuff_rdp.c:441
441 if (!zgfx_write_from_history(zgfx, distance, count))

The bug is easily reproducible with the captures I have; RDP traffic
runs between "Windows 10" and "Windows Server 2019 Datacenter".

Wireshark runs on Ubuntu:

- Wireshark: Version 3.6.2 (Git v3.6.2 packaged as 3.6.2-2)
- Ubuntu: $ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.1 LTS"

1. Is this issue known? I tried to look it up on gitlab but I did not
find anything relevant. Should I file an issue on gitlab?
2. Can the EGFX decoder be turned off? I need the decoder for virtual
channels though.

Thanks a lot,
Cristian