Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SEGV in jpegoptim.c:631, jpeg_read_header() #168

Open
schsiung opened this issue Jan 3, 2024 · 5 comments
Open

SEGV in jpegoptim.c:631, jpeg_read_header() #168

schsiung opened this issue Jan 3, 2024 · 5 comments

Comments

@schsiung
Copy link

schsiung commented Jan 3, 2024

Expected behavior and actual behavior.

SEGV_jpegoptim-1.4.7.tar.gz

Expect running without SEGV .

Steps to reproduce the problem.

  1. bin/jpegoptim out/default/crashes/id:000000,sig:11,src:000055,time:111839,execs:11762,op:havoc,rep:7 -o 1.jpg
[AFL++ 4547ba12d0d6] /data/openeuler/jpegoptim/jpegoptim-1.4.7/build/obj # bin/jpegoptim out/def
ault/crashes/id:000000,sig:11,src:000055,time:111839,execs:11762,op:havoc,rep:7 -o 1.jpg
out/default/crashes/id:000000,sig:11,src:000055,time:111839,execs:11762,op:havoc,rep:7 AddressSanitizer:DEADLYSIGNAL
=================================================================
==4092299==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x7fc08097ab95 bp 0x7fff8b6b04c0 sp 0x7fff8b6aff20 T0)
==4092299==The signal is caused by a READ memory access.
==4092299==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 0x7fc08097ab95  (/lib/x86_64-linux-gnu/libjpeg.so.8+0x23b95) (BuildId: c54abff9294357e28532a76a049a4cb2542fc15b)
    #1 0x7fc0809824ef  (/lib/x86_64-linux-gnu/libjpeg.so.8+0x2b4ef) (BuildId: c54abff9294357e28532a76a049a4cb2542fc15b)
    #2 0x7fc08098123e  (/lib/x86_64-linux-gnu/libjpeg.so.8+0x2a23e) (BuildId: c54abff9294357e28532a76a049a4cb2542fc15b)
    #3 0x7fc080974cce in jpeg_consume_input (/lib/x86_64-linux-gnu/libjpeg.so.8+0x1dcce) (BuildId: c54abff9294357e28532a76a049a4cb2542fc15b)
    #4 0x7fc080974f21 in jpeg_read_header (/lib/x86_64-linux-gnu/libjpeg.so.8+0x1df21) (BuildId: c54abff9294357e28532a76a049a4cb2542fc15b)
    #5 0x56080c4c5466 in main /data/openeuler/jpegoptim/jpegoptim-1.4.7/jpegoptim.c:631:3
    #6 0x7fc080738d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: a43bfc8428df6623cd498c9c0caeb91aec9be4f9)
    #7 0x7fc080738e3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f) (BuildId: a43bfc8428df6623cd498c9c0caeb91aec9be4f9)
    #8 0x56080c3ff454 in _start (/data/openeuler/jpegoptim/jpegoptim-1.4.7/build/obj/bin/jpegoptim+0x5e454) (BuildId: a3aaafbe2592aad4)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/lib/x86_64-linux-gnu/libjpeg.so.8+0x23b95) (BuildId: c54abff9294357e28532a76a049a4cb2542fc15b) 
==4092299==ABORTING 
  1. GDB info gdb bin/jpegoptim
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

  1. I have tried to link a static libjpeg.a, it gives more information:
[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
    #1 0x55a710e2ae93 in read_markers /data/openeuler/jpegoptim/jpegoptim-1.4.7/build/libjpeg-turbo/jdmarker.c:1107:12
    #2 0x55a710e4f721 in consume_markers /data/openeuler/jpegoptim/jpegoptim-1.4.7/build/libjpeg-turbo/jdinput.c:334:9
    #3 0x55a710e21052 in jpeg_consume_input /data/openeuler/jpegoptim/jpegoptim-1.4.7/build/libjpeg-turbo/jdapimin.c:320:15
    #4 0x55a710e20a0f in jpeg_read_header /data/openeuler/jpegoptim/jpegoptim-1.4.7/build/libjpeg-turbo/jdapimin.c:268:13
    #5 0x55a710deca4a in main /data/openeuler/jpegoptim/jpegoptim-1.4.7/jpegoptim.c:631:3
    #6 0x7f81f9cf0d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: a43bfc8428df6623cd498c9c0caeb91aec9be4f9)
    #7 0x7f81f9cf0e3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f) (BuildId: a43bfc8428df6623cd498c9c0caeb91aec9be4f9)
    #8 0x55a710d21434 in _start (/data/openeuler/jpegoptim/jpegoptim-1.4.7/jpegoptim+0xa4434) (BuildId: 4d794c3820837ef3)

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 <custom_init_source>, fill_input_buffer = 0x555555c59fd0 <custom_fill_input_buffer>, skip_input_data = 0xbebebebebebebebe, 
  resync_to_restart = 0x5555556fbfa0 <jpeg_resync_to_restart>, term_source = 0x555555c5cb20 <custom_term_source>}
(gdb) p *cinfo->src->skip_input_data
Cannot access memory at address 0xbebebebebebebebe

Operating system

[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 # 

version

jpegoptim-1.4.7

From: xiongshengchao@jyhlab.org.cn

@tjko
Copy link
Owner

tjko commented Jan 4, 2024

This would seem to be issue in libjpeg and not in jpegoptim?

@schsiung
Copy link
Author

schsiung commented Jan 4, 2024

@tjko thanks, I have reported the issue to libjpeg-turbo, wait for their reply

@schsiung
Copy link
Author

schsiung commented Jan 5, 2024

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

@schsiung
Copy link
Author

schsiung commented Jan 5, 2024

@tjko there are no more SEGV crashes using the same POC with jpegoptim v1.5.5, I suppose the issue was already fixed by 3401f25
It seems to be the same issue with
#107
CVE-2022-32325

@tjko
Copy link
Owner

tjko commented Jan 5, 2024

@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)...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants