Headline
CVE-2023-24751: NULL Pointer Dereference in function mc_chroma at motion.cc:244 · Issue #379 · strukturag/libde265
libde265 v1.0.10 was discovered to contain a NULL pointer dereference in the mc_chroma function at motion.cc. This vulnerability allows attackers to cause a Denial of Service (DoS) via a crafted input file.
Description
NULL Pointer Dereference in function mc_chroma at motion.cc:244
Version
git log
commit 1cf2999583ef8a90e11933ed70908e4e2c2d8872 (HEAD -> master, origin/master, origin/HEAD)
Steps to reproduce
git clone https://github.com/strukturag/libde265.git
cd libde265
./autogen.sh
export CFLAGS="-g -O0 -lpthread -fsanitize=address"
export CXXFLAGS="-g -O0 -lpthread -fsanitize=address"
export LDFLAGS="-fsanitize=address"
./configure --disable-shared
make -j
cd dec265
./dec265 ./poc_segv03.bin
WARNING: non-existing PPS referenced
WARNING: non-existing PPS referenced
WARNING: non-existing PPS referenced
WARNING: non-existing PPS referenced
WARNING: non-existing PPS referenced
WARNING: non-existing PPS referenced
WARNING: non-existing PPS referenced
WARNING: non-existing PPS referenced
WARNING: CTB outside of image area (concealing stream error...)
WARNING: maximum number of reference pictures exceeded
WARNING: faulty reference picture list
WARNING: maximum number of reference pictures exceeded
WARNING: maximum number of reference pictures exceeded
WARNING: CTB outside of image area (concealing stream error...)
AddressSanitizer:DEADLYSIGNAL
=================================================================
==7799==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x55b3b6a88832 bp 0x7ffcc9fb8d30 sp 0x7ffcc9fb5180 T0)
==7799==The signal is caused by a READ memory access.
==7799==Hint: address points to the zero page.
#0 0x55b3b6a88831 in void mc_chroma<unsigned char>(base_context const*, seq_parameter_set const*, int, int, int, int, short*, int, unsigned char const*, int, int, int, int) /home/fuzz/libde265/libde265/motion.cc:244
#1 0x55b3b6a80067 in generate_inter_prediction_samples(base_context*, slice_segment_header const*, de265_image*, int, int, int, int, int, int, int, PBMotion const*) /home/fuzz/libde265/libde265/motion.cc:412
#2 0x55b3b6a80edd in decode_prediction_unit(base_context*, slice_segment_header const*, de265_image*, PBMotionCoding const&, int, int, int, int, int, int, int, int) /home/fuzz/libde265/libde265/motion.cc:2141
#3 0x55b3b6968fb7 in read_prediction_unit(thread_context*, int, int, int, int, int, int, int, int, int) /home/fuzz/libde265/libde265/slice.cc:4136
#4 0x55b3b6971418 in read_coding_unit(thread_context*, int, int, int, int) /home/fuzz/libde265/libde265/slice.cc:4504
#5 0x55b3b69752e1 in read_coding_quadtree(thread_context*, int, int, int, int) /home/fuzz/libde265/libde265/slice.cc:4652
#6 0x55b3b69773db in decode_substream(thread_context*, bool, bool) /home/fuzz/libde265/libde265/slice.cc:4741
#7 0x55b3b697a0c2 in read_slice_segment_data(thread_context*) /home/fuzz/libde265/libde265/slice.cc:5054
#8 0x55b3b6883487 in decoder_context::decode_slice_unit_sequential(image_unit*, slice_unit*) /home/fuzz/libde265/libde265/decctx.cc:852
#9 0x55b3b6886ca0 in decoder_context::decode_slice_unit_parallel(image_unit*, slice_unit*) /home/fuzz/libde265/libde265/decctx.cc:954
#10 0x55b3b6887934 in decoder_context::decode_some(bool*) /home/fuzz/libde265/libde265/decctx.cc:739
#11 0x55b3b688d902 in decoder_context::decode(int*) /home/fuzz/libde265/libde265/decctx.cc:1338
#12 0x55b3b6852f9d in main /home/fuzz/libde265/dec265/dec265.cc:764
#13 0x7f184b1ce082 in __libc_start_main ../csu/libc-start.c:308
#14 0x55b3b68570dd in _start (/home/fuzz/libde265/dec265/dec265+0x240dd)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/fuzz/libde265/libde265/motion.cc:244 in void mc_chroma<unsigned char>(base_context const*, seq_parameter_set const*, int, int, int, int, short*, int, unsigned char const*, int, int, int, int)
==7799==ABORTING
POC
poc_segv03.bin
GDB
gdb --args ./dec265 ./poc_segv03.bin
─── Output/messages ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
WARNING: non-existing PPS referenced
WARNING: non-existing PPS referenced
WARNING: non-existing PPS referenced
WARNING: non-existing PPS referenced
WARNING: non-existing PPS referenced
WARNING: non-existing PPS referenced
WARNING: non-existing PPS referenced
WARNING: non-existing PPS referenced
WARNING: CTB outside of image area (concealing stream error...)
WARNING: maximum number of reference pictures exceeded
WARNING: faulty reference picture list
WARNING: maximum number of reference pictures exceeded
WARNING: maximum number of reference pictures exceeded
WARNING: CTB outside of image area (concealing stream error...)
Program received signal SIGSEGV, Segmentation fault.
0x00005555557c2324 in mc_chroma<unsigned char> (ctx=0x621000000100, sps=0x629000005210, mv_x=0, mv_y=2, xP=0, yP=0, out=0x7ffffffe6d60, out_stride=16, ref=0x0, ref_stride=0, nPbWC=8, nPbHC=16, bit_depth_C=8) at motion.cc:244
244 padbuf[x+extra_left + (y+extra_top)*(MAX_CU_SIZE+16)] = ref[ xA + yA*ref_stride ];
─── Assembly ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
0x00005555557c2316 mc_chroma<unsigned char>(base_context const*, seq_parameter_set const*, int, int, int, int, short*, int, unsigned char const*, int, int, int, int)+6304 and %edi,%edx
0x00005555557c2318 mc_chroma<unsigned char>(base_context const*, seq_parameter_set const*, int, int, int, int, short*, int, unsigned char const*, int, int, int, int)+6306 test %dl,%dl
0x00005555557c231a mc_chroma<unsigned char>(base_context const*, seq_parameter_set const*, int, int, int, int, short*, int, unsigned char const*, int, int, int, int)+6308 je 0x5555557c2324 <mc_chroma<unsigned char>(base_context const*, seq_parameter_set const*, int, int, int, int, short*, int, unsigned char const*, int, int, int, int)+6318>
0x00005555557c231c mc_chroma<unsigned char>(base_context const*, seq_parameter_set const*, int, int, int, int, short*, int, unsigned char const*, int, int, int, int)+6310 mov %rax,%rdi
0x00005555557c231f mc_chroma<unsigned char>(base_context const*, seq_parameter_set const*, int, int, int, int, short*, int, unsigned char const*, int, int, int, int)+6313 callq 0x555555570dd0 <__asan_report_load1@plt>
0x00005555557c2324 mc_chroma<unsigned char>(base_context const*, seq_parameter_set const*, int, int, int, int, short*, int, unsigned char const*, int, int, int, int)+6318 movzbl (%rcx),%ecx
0x00005555557c2327 mc_chroma<unsigned char>(base_context const*, seq_parameter_set const*, int, int, int, int, short*, int, unsigned char const*, int, int, int, int)+6321 lea -0x1610(%r15),%rdx
0x00005555557c232e mc_chroma<unsigned char>(base_context const*, seq_parameter_set const*, int, int, int, int, short*, int, unsigned char const*, int, int, int, int)+6328 movslq %esi,%rax
0x00005555557c2331 mc_chroma<unsigned char>(base_context const*, seq_parameter_set const*, int, int, int, int, short*, int, unsigned char const*, int, int, int, int)+6331 add %rdx,%rax
0x00005555557c2334 mc_chroma<unsigned char>(base_context const*, seq_parameter_set const*, int, int, int, int, short*, int, unsigned char const*, int, int, int, int)+6334 mov %rax,%rdx
─── Breakpoints ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
─── Expressions ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
─── History ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
─── Memory ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
─── Registers ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
rax 0x0000000000000000 rbx 0x000055555581d4e0 rcx 0x0000000000000000 rdx 0x0000000000000000 rsi 0x0000000000000000 rdi 0x0000000000000000 rbp 0x00007ffffffe29f0 rsp 0x00007ffffffdee60
r8 0x0000000000000000 r9 0x0000000000000000 r10 0x00007ffffffe2a10 r11 0x00007ffffffe6d60 r12 0x00007ffffffe2a10 r13 0x00000fffffffbde0 r14 0x00007ffffffdef00 r15 0x00007ffffffe29c0
rip 0x00005555557c2324 eflags [ PF ZF IF RF ] cs 0x00000033 ss 0x0000002b ds 0x00000000 es 0x00000000 fs 0x00000000 gs 0x00000000
─── Source ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
239 for (int x=-extra_left;x<nPbWC+extra_right;x++) {
240
241 int xA = Clip3(0,wC-1,x + xIntOffsC);
242 int yA = Clip3(0,hC-1,y + yIntOffsC);
243
244 padbuf[x+extra_left + (y+extra_top)*(MAX_CU_SIZE+16)] = ref[ xA + yA*ref_stride ];
245 }
246 }
247
248 src_ptr = &padbuf[extra_left + extra_top*(MAX_CU_SIZE+16)];
─── Stack ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
[0] from 0x00005555557c2324 in mc_chroma<unsigned char>(base_context const*, seq_parameter_set const*, int, int, int, int, short*, int, unsigned char const*, int, int, int, int)+6318 at motion.cc:244
[1] from 0x000055555579fcb0 in generate_inter_prediction_samples(base_context*, slice_segment_header const*, de265_image*, int, int, int, int, int, int, int, PBMotion const*)+11224 at motion.cc:412
[2] from 0x00005555557b92dd in decode_prediction_unit(base_context*, slice_segment_header const*, de265_image*, PBMotionCoding const&, int, int, int, int, int, int, int, int)+496 at motion.cc:2141
[3] from 0x0000555555683258 in read_prediction_unit(thread_context*, int, int, int, int, int, int, int, int, int)+2790 at slice.cc:4136
[4] from 0x0000555555687afa in read_coding_unit(thread_context*, int, int, int, int)+15196 at slice.cc:4504
[5] from 0x0000555555689d5e in read_coding_quadtree(thread_context*, int, int, int, int)+3873 at slice.cc:4652
[6] from 0x00005555556729f1 in read_coding_tree_unit(thread_context*)+1351 at slice.cc:2861
[7] from 0x000055555568aec2 in decode_substream(thread_context*, bool, bool)+4333 at slice.cc:4741
[8] from 0x000055555568e986 in read_slice_segment_data(thread_context*)+1762 at slice.cc:5054
[9] from 0x000055555558c18a in decoder_context::decode_slice_unit_sequential(image_unit*, slice_unit*)+3516 at decctx.cc:852
[+]
─── Threads ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
[1] id 14091 name dec265 from 0x00005555557c2324 in mc_chroma<unsigned char>(base_context const*, seq_parameter_set const*, int, int, int, int, short*, int, unsigned char const*, int, int, int, int)+6318 at motion.cc:244
─── Variables ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
arg ctx = 0x621000000100: {<error_queue> = {warnings = {[0] = DE265_WARNING_CTB_OUTSIDE_IMAGE_AREA, […, sps = 0x629000005210: {sps_read = true,video_parameter_set_id = 12 '\f',sps_max_sub_layers = 5 '\…, mv_x = 0, mv_y = 2, xP = 0, yP = 0, out = 0x7ffffffe6d60: 0, out_stride = 16, ref = 0x0: Cannot access memory at address 0x0, ref_stride = 0, nPbWC = 8, nPbHC = 16, bit_depth_C = 8
loc xA = 0, yA = 0, x = -1, y = -1, padbuf = '\000' <repeats 5359 times>, src_ptr = 0x0: Cannot access memory at address 0x0, src_stride = 0, extra_left = 1, extra_right = 2, extra_bottom = 2, extra_top = 1, __PRETTY_FUNCTION__ = "void mc_chroma(const base_context*, const seq_parameter_set*, int, int, int, int, int16_t*, int, co…, shift3 = 6, wC = 16, hC = 48, xFracC = 0, yFracC = 2, xIntOffsC = 0, yIntOffsC = 0, mcbuffer = {[0] = 0 <repeats 4544 times>}
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
>>> p ref
$1 = (const unsigned char *) 0x0
>>>
Impact
This vulnerability is capable of crashing software, causing a denial of service via a crafted input file.
Related news
Gentoo Linux Security Advisory 202408-20 - Multiple vulnerabilities have been discovered in libde265, the worst of which could lead to arbitrary code execution. Versions greater than or equal to 1.0.11 are affected.
Ubuntu Security Notice 6659-1 - It was discovered that libde265 could be made to write out of bounds. If a user or automated system were tricked into opening a specially crafted file, an attacker could possibly use this issue to cause a denial of service or execute arbitrary code. It was discovered that libde265 could be made to read out of bounds. If a user or automated system were tricked into opening a specially crafted file, an attacker could possibly use this issue to cause a denial of service.