gopro / gpr

General Purpose Raw image format
Apache License 2.0
116 stars 33 forks source link

Crash when parsing a malformed GPR file #35

Open retpoline opened 2 years ago

retpoline commented 2 years ago

Hi folks,

A crash was found while fuzz testing of the gpr_tools binary which can be triggered via a malformed GPR file. Although this malformed file only crashes the program as-is, it might have the potential to be crafted further and create a security issue where these kinds of files would be able compromise the process's memory through taking advantage of affordances given by memory corruption. It's recommend to harden the code to prevent these kinds of bugs as it could greatly mitigate such this issue and even future bugs.

You can download the crashing gpr file (~3mb file size) from Ufile to debug and understand where the code is crashing.

$ ./gpr_tools -i crash.gpr -o test.dng
[    0-ms]  GPR Tools Version 1.0.0 [master @ 96b11fc] [Linux][GCC 9.3.0][64 bit] 
[    0-ms]  Input File: crash.gpr 
[    0-ms]  Output File: test.dng 
[    4-ms] [BEG] gpr_convert_gpr_to_dng() source/lib/gpr_sdk/private/gpr.cpp (line 1748)
Segmentation fault (core dumped)

(gdb) r -i crash.gpr -o test.dng
Starting program: gpr_tools -i crash.gpr -o test.dng
[    0-ms]  GPR Tools Version 1.0.0 [master @ 96b11fc] [Linux][GCC 9.3.0][64 bit] 
[    0-ms]  Input File: crash.gpr 
[    0-ms]  Output File: test.dng 
[    5-ms] [BEG] gpr_convert_gpr_to_dng() source/lib/gpr_sdk/private/gpr.cpp (line 1748)

Program received signal SIGSEGV, Segmentation fault.
0x000055555567b31a in UpdateCodecState ()
(gdb) i r
rax            0x7ffffffec2b0      140737488274096
rbx            0x2ea2c0            3056320
rcx            0x2                 2
rdx            0xaf0e              44814
rsi            0x3                 3
rdi            0x2d                45
rbp            0x7ffffffec1a0      0x7ffffffec1a0
rsp            0x7ffffffec140      0x7ffffffec140
r8             0x5555591b8240      93825055556160
r9             0x7ffff7c59c20      140737350310944
r10            0x5555591d9000      93825055690752
r11            0xfffffffffffff000  -4096
r12            0x555555938f70      93824996314992
r13            0x555555595e30      93824992501296
r14            0x3                 3
r15            0x7fffffffe190      140737488347536
rip            0x55555567b31a      0x55555567b31a <UpdateCodecState+1906>
eflags         0x10202             [ IF RF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0

(gdb) x/i $rip
=> 0x55555567b31a <UpdateCodecState+1906>:  movzbl 0x11(%rax,%rdx,8),%eax

(gdb) bt
#0  0x000055555567b31a in UpdateCodecState ()
#1  0x0000555555679e08 in DecodeSingleImage ()
#2  0x0000555555679d5b in DecodingProcess ()
#3  0x000055555567981c in DecodeImage ()
#4  0x0000555555679280 in vc5_decoder_process ()
#5  0x0000555555586e3a in DecodeVC5(dng_image&, gpr_buffer_auto&, VC5_DECODER_PIXEL_FORMAT) ()
#6  0x00005555555870a8 in gpr_read_image::ReadTile(dng_host&, dng_ifd const&, dng_stream&, dng_image&, dng_rect const&, unsigned int, unsigned int, unsigned int, AutoPtr<dng_memory_block>&, AutoPtr<dng_memory_block>&, AutoPtr<dng_memory_block>&) ()
#7  0x00005555555ef397 in dng_read_image::Read(dng_host&, dng_ifd const&, dng_stream&, dng_image&, dng_jpeg_image*, dng_fingerprint*) ()
#8  0x00005555555d989d in dng_negative::ReadVc5Image(dng_host&, dng_stream&, dng_info&, dng_read_image&) ()
#9  0x000055555557c9e1 in read_dng(gpr_allocator const*, dng_stream*, gpr_buffer_auto*, gpr_buffer_auto*, gpr_parameters*, bool*) ()
#10 0x0000555555581df1 in gpr_convert_gpr_to_dng ()
#11 0x000055555557a9c4 in dng_convert_main ()
#12 0x0000555555577885 in main ()

(gdb) exploitable
Description: Access violation
Short description: AccessViolation (21/22)
Hash: 7b9a2f770e5e19c99d35e5d33ef3baf3.7ded8a2db954fdc92d946a58e3a35451
Exploitability Classification: UNKNOWN
Explanation: The target crashed due to an access violation but there is not enough additional information available to determine exploitability.