Open schsiung opened 7 months ago
This would seem to be issue in libjpeg and not in jpegoptim?
@tjko thanks, I have reported the issue to libjpeg-turbo
, wait for their reply
referring the comment, https://github.com/libjpeg-turbo/libjpeg-turbo/security/advisories/GHSA-mm58-28hq-3c32#advisory-comment-93367 It will check with the latest jpegoptim version of v1.5.5
@tjko there are no more SEGV crashes using the same POC with jpegoptim v1.5.5, I suppose the issue was already fixed by https://github.com/tjko/jpegoptim/commit/3401f250ace692a5b23eac1617dc429eb3566f9f
It seems to be the same issue with
https://github.com/tjko/jpegoptim/issues/107
CVE-2022-32325
@schsiung, yes I think you're correct. I had forgotten about the 'custom' memory manager that jpegoptim uses. It can make it look like there is problem in the libjpeg, when the problem is actually in jpegoptim (jpegsrc.c)...
Expected behavior and actual behavior.
SEGV_jpegoptim-1.4.7.tar.gz
Expect running without SEGV .
Steps to reproduce the problem.
bin/jpegoptim out/default/crashes/id:000000,sig:11,src:000055,time:111839,execs:11762,op:havoc,rep:7 -o 1.jpg
AddressSanitizer can not provide additional info. SUMMARY: AddressSanitizer: SEGV (/lib/x86_64-linux-gnu/libjpeg.so.8+0x23b95) (BuildId: c54abff9294357e28532a76a049a4cb2542fc15b) ==4092299==ABORTING
Reading symbols from bin/jpegoptim... (gdb) break jpegoptim.c:631 Breakpoint 1 at 0x12445a: file jpegoptim.c, line 631. (gdb) break jpeg_read_header Breakpoint 2 at 0x134cf0 (gdb) break jpeg_consume_input Function "jpeg_consume_input" not defined. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 3 (jpeg_consume_input) pending. (gdb) run out/default/crashes/id:000000,sig:11,src:000055,time:111839,execs:11762,op:havoc,rep:7 -o 1.jpg Starting program: /data/openeuler/jpegoptim/jpegoptim-1.4.7/build/obj/bin/jpegoptim out/default/crashes/id:000000,sig:11,src:000055,time:111839,execs:11762,op:havoc,rep:7 -o 1.jpg [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". out/default/crashes/id:000000,sig:11,src:000055,time:111839,execs:11762,op:havoc,rep:7 Breakpoint 1, main (argc=4, argv=0x7fffffffe178) at jpegoptim.c:631 631 jpeg_read_header(&dinfo, TRUE); (gdb) p dinfo $1 = {err = 0x7fffffff9900, mem = 0x60f000000040, progress = 0x0, client_data = 0x0, is_decompressor = 1, global_state = 200, src = 0x61d0000002a0, image_width = 0, image_height = 0, num_components = 0, jpeg_color_space = JCS_UNKNOWN, out_color_space = JCS_UNKNOWN, scale_num = 0, scale_denom = 0, output_gamma = 0, buffered_image = 0, raw_data_out = 0, dct_method = JDCT_ISLOW, do_fancy_upsampling = 0, do_block_smoothing = 0, quantize_colors = 0, dither_mode = JDITHER_NONE, two_pass_quantize = 0, desired_number_of_colors = 0, enable_1pass_quant = 0, enable_external_quant = 0, enable_2pass_quant = 0, output_width = 0, output_height = 0, out_color_components = 0, output_components = 0, rec_outbuf_height = 0, actual_number_of_colors = 0, colormap = 0x0, output_scanline = 0, input_scan_number = 0, input_iMCU_row = 0, output_scan_number = 0, output_iMCU_row = 0, coef_bits = 0x0, quant_tbl_ptrs = {0x0, 0x0, 0x0, 0x0}, dc_huff_tbl_ptrs = {0x0, 0x0, 0x0, 0x0}, ac_huff_tbl_ptrs = {0x0, 0x0, 0x0, 0x0}, data_precision = 0, comp_info = 0x0, is_baseline = 0, progressive_mode = 0, arith_code = 0, arith_dc_L = '\000' <repeats 15 times>, arith_dc_U = '\000' <repeats 15 times>, arith_ac_K = '\000' <repeats 15 times>, restart_interval = 0, saw_JFIF_marker = 0, JFIF_major_version = 0 '\000', JFIF_minor_version = 0 '\000', density_unit = 0 '\000', X_density = 0, Y_density = 0, saw_Adobe_marker = 0, Adobe_transform = 0 '\000', CCIR601_sampling = 0, marker_list = 0x0, max_h_samp_factor = 0, max_v_samp_factor = 0, min_DCT_h_scaled_size = 0, min_DCT_v_scaled_size = 0, total_iMCU_rows = 0, sample_range_limit = 0x0, comps_in_scan = 0, cur_comp_info = {0x0, 0x0, 0x0, 0x0}, MCUs_per_row = 0, MCU_rows_in_scan = 0, blocks_in_MCU = 0, MCU_membership = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Ss = 0, Se = 0, Ah = 0, Al = 0, block_size = 0, natural_order = 0x0, lim_Se = 0, unread_marker = 0, master = 0x61d000000200, main = 0x0, coef = 0x0, post = 0x0, inputctl = 0x61d0000001c0, marker = 0x61d0000000a0, entropy = 0x0, idct = 0x0, upsample = 0x0, cconvert = 0x0, cquantize = 0x0} (gdb) n
Breakpoint 2, 0x00007ffff7e6aef0 in jpeg_read_header () from /lib/x86_64-linux-gnu/libjpeg.so.8 (gdb) n Single stepping until exit from function jpeg_read_header, which has no line number information.
Breakpoint 3, 0x00007ffff7e6ac60 in jpeg_consume_input () from /lib/x86_64-linux-gnu/libjpeg.so.8 (gdb) n Single stepping until exit from function jpeg_consume_input, which has no line number information.
Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7e70b95 in ?? () from /lib/x86_64-linux-gnu/libjpeg.so.8 (gdb) bt
0 0x00007ffff7e70b95 in ?? () from /lib/x86_64-linux-gnu/libjpeg.so.8
1 0x00007ffff7e784f0 in ?? () from /lib/x86_64-linux-gnu/libjpeg.so.8
2 0x00007ffff7e7723f in ?? () from /lib/x86_64-linux-gnu/libjpeg.so.8
3 0x00007ffff7e6accf in jpeg_consume_input () from /lib/x86_64-linux-gnu/libjpeg.so.8
4 0x00007ffff7e6af22 in jpeg_read_header () from /lib/x86_64-linux-gnu/libjpeg.so.8
5 0x0000555555678467 in main (argc=4, argv=0x7fffffffe178) at jpegoptim.c:631
(gdb) q
[AFL++ 4547ba12d0d6] /data/openeuler/jpegoptim/jpegoptim-1.4.7/build/obj # ../../jpegoptim out/default/crashes/id:000000,sig:11,src:000055,time:111839,execs:11762,op:havoc,rep:7 out/default/crashes/id:000000,sig:11,src:000055,time:111839,execs:11762,op:havoc,rep:7 AddressSanitizer:DEADLYSIGNAL
==813934==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x55a710e410ae bp 0x7ffd21d5a550 sp 0x7ffd21d5a4f0 T0) ==813934==The signal is caused by a READ memory access. ==813934==Hint: this fault was caused by a dereference of a high value address (see register values below). Disassemble the provided pc to learn which register was used.
0 0x55a710e410ae in skip_variable /data/openeuler/jpegoptim/jpegoptim-1.4.7/build/libjpeg-turbo/jdmarker.c:876:5
AddressSanitizer can not provide additional info. SUMMARY: AddressSanitizer: SEGV /data/openeuler/jpegoptim/jpegoptim-1.4.7/build/libjpeg-turbo/jdmarker.c:876:5 in skip_variable ==813934==ABORTING
Reading symbols from ../../jpegoptim... (gdb) run out/default/crashes/id:000000,sig:11,src:000055,time:111839,execs:11762,op:havoc,rep:7 Starting program: /data/openeuler/jpegoptim/jpegoptim-1.4.7/jpegoptim out/default/crashes/id:000000,sig:11,src:000055,time:111839,execs:11762,op:havoc,rep:7 [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". out/default/crashes/id:000000,sig:11,src:000055,time:111839,execs:11762,op:havoc,rep:7 Program received signal SIGSEGV, Segmentation fault. 0x00005555557180ae in skip_variable (cinfo=0x7fffffff91a0) at /data/openeuler/jpegoptim/jpegoptim-1.4.7/build/libjpeg-turbo/jdmarker.c:876 876 (*cinfo->src->skip_input_data) (cinfo, (long)length); (gdb) bt
0 0x00005555557180ae in skip_variable (cinfo=0x7fffffff91a0) at /data/openeuler/jpegoptim/jpegoptim-1.4.7/build/libjpeg-turbo/jdmarker.c:876
1 0x0000555555701e94 in read_markers (cinfo=0x7fffffff91a0) at /data/openeuler/jpegoptim/jpegoptim-1.4.7/build/libjpeg-turbo/jdmarker.c:1107
2 0x0000555555726722 in consume_markers (cinfo=0x7fffffff91a0) at /data/openeuler/jpegoptim/jpegoptim-1.4.7/build/libjpeg-turbo/jdinput.c:334
3 0x00005555556f8053 in jpeg_consume_input (cinfo=0x7fffffff91a0) at /data/openeuler/jpegoptim/jpegoptim-1.4.7/build/libjpeg-turbo/jdapimin.c:320
4 0x00005555556f7a10 in jpeg_read_header (cinfo=0x7fffffff91a0, require_image=1) at /data/openeuler/jpegoptim/jpegoptim-1.4.7/build/libjpeg-turbo/jdapimin.c:268
5 0x00005555556c3a4b in main (argc=2, argv=0x7fffffffe1a8) at jpegoptim.c:631
(gdb) p cinfo $1 = {err = 0x7fffffff9940, mem = 0x60f000000040, progress = 0x0, client_data = 0x0, is_decompressor = 1, global_state = 201, src = 0x61c000000260, image_width = 0, image_height = 0, num_components = 0, jpeg_color_space = JCS_UNKNOWN, out_color_space = JCS_UNKNOWN, scale_num = 0, scale_denom = 0, output_gamma = 0, buffered_image = 0, raw_data_out = 0, dct_method = JDCT_ISLOW, do_fancy_upsampling = 0, do_block_smoothing = 0, quantize_colors = 0, dither_mode = JDITHER_NONE, two_pass_quantize = 0, desired_number_of_colors = 0, enable_1pass_quant = 0, enable_external_quant = 0, enable_2pass_quant = 0, output_width = 0, output_height = 0, out_color_components = 0, output_components = 0, rec_outbuf_height = 0, actual_number_of_colors = 0, colormap = 0x0, output_scanline = 0, input_scan_number = 0, input_iMCU_row = 0, output_scan_number = 0, output_iMCU_row = 0, coef_bits = 0x0, quant_tbl_ptrs = {0x61c0000002e8, 0x0, 0x0, 0x0}, dc_huff_tbl_ptrs = {0x0, 0x0, 0x0, 0x0}, ac_huff_tbl_ptrs = {0x0, 0x0, 0x0, 0x0}, data_precision = 8, comp_info = 0x0, is_baseline = 0, progressive_mode = 0, arith_code = 0, arith_dc_L = '\000' <repeats 15 times>, arith_dc_U = '\001' <repeats 16 times>, arith_ac_K = '\005' <repeats 16 times>, restart_interval = 0, saw_JFIF_marker = 0, JFIF_major_version = 1 '\001', JFIF_minor_version = 1 '\001', density_unit = 0 '\000', X_density = 1, Y_density = 1, saw_Adobe_marker = 0, Adobe_transform = 0 '\000', CCIR601_sampling = 0, marker_list = 0x607000000038, max_h_samp_factor = 0, max_v_samp_factor = 0, min_DCT_h_scaled_size = 0, min_DCT_v_scaled_size = 0, total_iMCU_rows = 0, sample_range_limit = 0x0, comps_in_scan = 0, cur_comp_info = {0x0, 0x0, 0x0, 0x0}, MCUs_per_row = 0, MCU_rows_in_scan = 0, blocks_in_MCU = 0, MCU_membership = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Ss = 0, Se = 0, Ah = 0, Al = 0, block_size = 0, natural_order = 0x0, lim_Se = 0, unread_marker = 220, master = 0x61c0000001d0, main = 0x0, coef = 0x0, post = 0x0, inputctl = 0x61c0000001a0, marker = 0x61c000000098, entropy = 0x0, idct = 0x0, upsample = 0x0, cconvert = 0x0, cquantize = 0x0} (gdb) p cinfo->src $2 = {next_input_byte = 0x621000000178 "\001VZZxix\353\202\202\353", '\377' <repeats 18 times>, "\177\377\377\377\377\377\377\377\377\377\364", '\377' <repeats 26 times>, "\300", bytes_in_buffer = 280, init_source = 0x555555c59a80, fill_input_buffer = 0x555555c59fd0 , skip_input_data = 0xbebebebebebebebe,
resync_to_restart = 0x5555556fbfa0 , term_source = 0x555555c5cb20 }
(gdb) p *cinfo->src->skip_input_data
Cannot access memory at address 0xbebebebebebebebe
[AFL++ 4547ba12d0d6] /data/openeuler/jpegoptim/jpegoptim-1.4.7/build # uname -a Linux 4547ba12d0d6 5.15.0-91-generic #101-Ubuntu SMP Tue Nov 14 13:30:08 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux [AFL++ 4547ba12d0d6] /data/openeuler/jpegoptim/jpegoptim-1.4.7/build #