# Problem

Running `gst-discoverer-1.0 Dune_trunc.h265` causes a segfault in `libde265.so`.
`Dune_trunc.h265` contains the first 10 seconds of the 4K h265 bitstream for the movie Dune.
Running `dec265` didn't have any problems with this file.

[Dune_trunc.zip](https://github.com/strukturag/libde265/files/12903872/Dune_trunc.zip)

# Debugging

I decided to post an issue on `libde265` because I think that the issue boils down to a double free in `libde265`.
If `gstreamer` itself is the more likely culprit I'll repost this issue there.

<details>
<summary>gdb backtrace</summary>

```
Thread 4 "h265parse0:sink" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff5a8e6c0 (LWP 1370002)]
0x00007ffff5230aa4 in image_unit::~image_unit (this=0x7fffec779580, __in_chrg=<optimized out>) at decctx.cc:194
194         delete tasks[i];                                                                                                                                                        
(gdb) bt
#0  0x00007ffff5230aa4 in image_unit::~image_unit (this=0x7fffec779580, __in_chrg=<optimized out>) at decctx.cc:194
#1  0x00007ffff5233c3e in decoder_context::decode_some (this=this@entry=0x7fffec034aa0, did_work=did_work@entry=0x7ffff5a8d460) at decctx.cc:796
#2  0x00007ffff5235ab0 in decoder_context::read_slice_NAL (this=this@entry=0x7fffec034aa0, reader=..., nal=nal@entry=0x7fffec016670, nal_hdr=...) at decctx.cc:698
#3  0x00007ffff5235c91 in decoder_context::decode_NAL (this=this@entry=0x7fffec034aa0, nal=0x7fffec016670) at decctx.cc:1240
#4  0x00007ffff5235f8c in decoder_context::decode (this=0x7fffec034aa0, more=0x7ffff5a8d56c) at decctx.cc:1328
#5  0x00007ffff5c2bf43 in gst_libde265_dec_handle_frame () from /nix/store/m986c3np2pll6s48kvbw59bi9rmb80qm-gst-plugins-bad-1.22.5/lib/gstreamer-1.0/libgstde265.so
#6  0x00007ffff7989ce2 in gst_video_decoder_decode_frame () from /nix/store/4k1pg5wr83dk829qzfispkskdwr2x038-gst-plugins-base-1.22.5/lib/libgstvideo-1.0.so.0
#7  0x00007ffff798a16a in gst_video_decoder_chain_forward () from /nix/store/4k1pg5wr83dk829qzfispkskdwr2x038-gst-plugins-base-1.22.5/lib/libgstvideo-1.0.so.0
#8  0x00007ffff798cd5a in gst_video_decoder_chain () from /nix/store/4k1pg5wr83dk829qzfispkskdwr2x038-gst-plugins-base-1.22.5/lib/libgstvideo-1.0.so.0
#9  0x00007ffff7e33ee9 in gst_pad_chain_data_unchecked () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstreamer-1.0.so.0
#10 0x00007ffff7e363f1 in gst_pad_push_data () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstreamer-1.0.so.0
#11 0x00007ffff7e3d76b in gst_pad_push () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstreamer-1.0.so.0
#12 0x00007ffff78c7d40 in gst_base_transform_chain () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstbase-1.0.so.0
#13 0x00007ffff7e33ee9 in gst_pad_chain_data_unchecked () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstreamer-1.0.so.0
#14 0x00007ffff7e363f1 in gst_pad_push_data () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstreamer-1.0.so.0
#15 0x00007ffff7e3d76b in gst_pad_push () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstreamer-1.0.so.0
#16 0x00007ffff78a85f8 in gst_base_parse_push_frame () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstbase-1.0.so.0
#17 0x00007ffff5bcbe6c in gst_h265_parse_handle_frame () from /nix/store/m986c3np2pll6s48kvbw59bi9rmb80qm-gst-plugins-bad-1.22.5/lib/gstreamer-1.0/libgstvideoparsersbad.so
#18 0x00007ffff78a33b9 in gst_base_parse_handle_buffer () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstbase-1.0.so.0
#19 0x00007ffff78a3bb7 in gst_base_parse_scan_frame () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstbase-1.0.so.0
#20 0x00007ffff78a704e in gst_base_parse_loop () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstbase-1.0.so.0
#21 0x00007ffff7e6d911 in gst_task_func () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstreamer-1.0.so.0
#22 0x00007ffff7c8911a in g_thread_pool_thread_proxy (data=<optimized out>) at ../glib/gthreadpool.c:350
#23 0x00007ffff7c887cd in g_thread_proxy (data=0x7ffff0000d40) at ../glib/gthread.c:831
#24 0x00007ffff7a9bdd4 in start_thread (arg=<optimized out>) at pthread_create.c:444
#25 0x00007ffff7b1d9b0 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
```

</details>

Here is the actual frame where a `delete` seems to cause the segfault.

```
(gdb) frame
#0  0x00007ffff5230aa4 in image_unit::~image_unit (this=0x7fffec779580, __in_chrg=<optimized out>) at decctx.cc:194
194	    delete tasks[i];
(gdb) print this->tasks[i]
$5 = (thread_task *) 0x7fffef3a4520
```

My first guess would be a double free in the `image_unit` data structure, though I haven't dug into `libde265` code yet.

# System

```
$ gst-discoverer-1.0 --gst-version
GStreamer Core Library version 1.22.5
```

```
$ dec265 --help
 dec265  v1.0.12
```

```
$ uname -a
Linux yoga9 6.5.6 #1-NixOS SMP PREEMPT_DYNAMIC Fri Oct  6 11:16:31 UTC 2023 x86_64 GNU/Linux
```

```
$ cat /etc/os-release
BUG_REPORT_URL="https://github.com/NixOS/nixpkgs/issues"
BUILD_ID="23.11.20231009.f99e5f0"
DOCUMENTATION_URL="https://nixos.org/learn.html"
HOME_URL="https://nixos.org/"
ID=nixos
LOGO="nix-snowflake"
NAME=NixOS
PRETTY_NAME="NixOS 23.11 (Tapir)"
SUPPORT_URL="https://nixos.org/community.html"
VERSION="23.11 (Tapir)"
VERSION_CODENAME=tapir
VERSION_ID="23.11"
```

Segfault in `libde265` in `gst-discoverer-1.0`
This is a GitHub Issue
repo:libde265
owner:strukturag
Title : Segfault in `libde265` in `gst-discoverer-1.0`
Issue date:

--- start body ---
# Problem

Running `gst-discoverer-1.0 Dune_trunc.h265` causes a segfault in `libde265.so`.
`Dune_trunc.h265` contains the first 10 seconds of the 4K h265 bitstream for the movie Dune.
Running `dec265` didn't have any problems with this file.

[Dune_trunc.zip](https://github.com/strukturag/libde265/files/12903872/Dune_trunc.zip)

# Debugging

I decided to post an issue on `libde265` because I think that the issue boils down to a double free in `libde265`.
If `gstreamer` itself is the more likely culprit I'll repost this issue there.

<details>
<summary>gdb backtrace</summary>

```
Thread 4 "h265parse0:sink" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff5a8e6c0 (LWP 1370002)]
0x00007ffff5230aa4 in image_unit::~image_unit (this=0x7fffec779580, __in_chrg=<optimized out>) at decctx.cc:194
194         delete tasks[i];                                                                                                                                                        
(gdb) bt
#0  0x00007ffff5230aa4 in image_unit::~image_unit (this=0x7fffec779580, __in_chrg=<optimized out>) at decctx.cc:194
#1  0x00007ffff5233c3e in decoder_context::decode_some (this=this@entry=0x7fffec034aa0, did_work=did_work@entry=0x7ffff5a8d460) at decctx.cc:796
#2  0x00007ffff5235ab0 in decoder_context::read_slice_NAL (this=this@entry=0x7fffec034aa0, reader=..., nal=nal@entry=0x7fffec016670, nal_hdr=...) at decctx.cc:698
#3  0x00007ffff5235c91 in decoder_context::decode_NAL (this=this@entry=0x7fffec034aa0, nal=0x7fffec016670) at decctx.cc:1240
#4  0x00007ffff5235f8c in decoder_context::decode (this=0x7fffec034aa0, more=0x7ffff5a8d56c) at decctx.cc:1328
#5  0x00007ffff5c2bf43 in gst_libde265_dec_handle_frame () from /nix/store/m986c3np2pll6s48kvbw59bi9rmb80qm-gst-plugins-bad-1.22.5/lib/gstreamer-1.0/libgstde265.so
#6  0x00007ffff7989ce2 in gst_video_decoder_decode_frame () from /nix/store/4k1pg5wr83dk829qzfispkskdwr2x038-gst-plugins-base-1.22.5/lib/libgstvideo-1.0.so.0
#7  0x00007ffff798a16a in gst_video_decoder_chain_forward () from /nix/store/4k1pg5wr83dk829qzfispkskdwr2x038-gst-plugins-base-1.22.5/lib/libgstvideo-1.0.so.0
#8  0x00007ffff798cd5a in gst_video_decoder_chain () from /nix/store/4k1pg5wr83dk829qzfispkskdwr2x038-gst-plugins-base-1.22.5/lib/libgstvideo-1.0.so.0
#9  0x00007ffff7e33ee9 in gst_pad_chain_data_unchecked () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstreamer-1.0.so.0
#10 0x00007ffff7e363f1 in gst_pad_push_data () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstreamer-1.0.so.0
#11 0x00007ffff7e3d76b in gst_pad_push () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstreamer-1.0.so.0
#12 0x00007ffff78c7d40 in gst_base_transform_chain () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstbase-1.0.so.0
#13 0x00007ffff7e33ee9 in gst_pad_chain_data_unchecked () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstreamer-1.0.so.0
#14 0x00007ffff7e363f1 in gst_pad_push_data () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstreamer-1.0.so.0
#15 0x00007ffff7e3d76b in gst_pad_push () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstreamer-1.0.so.0
#16 0x00007ffff78a85f8 in gst_base_parse_push_frame () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstbase-1.0.so.0
#17 0x00007ffff5bcbe6c in gst_h265_parse_handle_frame () from /nix/store/m986c3np2pll6s48kvbw59bi9rmb80qm-gst-plugins-bad-1.22.5/lib/gstreamer-1.0/libgstvideoparsersbad.so
#18 0x00007ffff78a33b9 in gst_base_parse_handle_buffer () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstbase-1.0.so.0
#19 0x00007ffff78a3bb7 in gst_base_parse_scan_frame () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstbase-1.0.so.0
#20 0x00007ffff78a704e in gst_base_parse_loop () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstbase-1.0.so.0
#21 0x00007ffff7e6d911 in gst_task_func () from /nix/store/z964cncjvwsiic8bphinlkb5z99rr25f-gstreamer-1.22.5/lib/libgstreamer-1.0.so.0
#22 0x00007ffff7c8911a in g_thread_pool_thread_proxy (data=<optimized out>) at ../glib/gthreadpool.c:350
#23 0x00007ffff7c887cd in g_thread_proxy (data=0x7ffff0000d40) at ../glib/gthread.c:831
#24 0x00007ffff7a9bdd4 in start_thread (arg=<optimized out>) at pthread_create.c:444
#25 0x00007ffff7b1d9b0 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
```

</details>

Here is the actual frame where a `delete` seems to cause the segfault.

```
(gdb) frame
#0  0x00007ffff5230aa4 in image_unit::~image_unit (this=0x7fffec779580, __in_chrg=<optimized out>) at decctx.cc:194
194	    delete tasks[i];
(gdb) print this->tasks[i]
$5 = (thread_task *) 0x7fffef3a4520
```

My first guess would be a double free in the `image_unit` data structure, though I haven't dug into `libde265` code yet.

# System

```
$ gst-discoverer-1.0 --gst-version
GStreamer Core Library version 1.22.5
```

```
$ dec265 --help
 dec265  v1.0.12
```

```
$ uname -a
Linux yoga9 6.5.6 #1-NixOS SMP PREEMPT_DYNAMIC Fri Oct  6 11:16:31 UTC 2023 x86_64 GNU/Linux
```

```
$ cat /etc/os-release
BUG_REPORT_URL="https://github.com/NixOS/nixpkgs/issues"
BUILD_ID="23.11.20231009.f99e5f0"
DOCUMENTATION_URL="https://nixos.org/learn.html"
HOME_URL="https://nixos.org/"
ID=nixos
LOGO="nix-snowflake"
NAME=NixOS
PRETTY_NAME="NixOS 23.11 (Tapir)"
SUPPORT_URL="https://nixos.org/community.html"
VERSION="23.11 (Tapir)"
VERSION_CODENAME=tapir
VERSION_ID="23.11"
```

--- end body ---

A segmentation fault in `libde265` when used with `gst-discoverer-1.0` indicates a potential vulnerability related to memory management, specifically a double free or invalid memory access in the `image_unit` destructor. This could lead to application crashes or exploitation if an attacker can control the input to the decoder.