New issue
Advanced search Search tips

Issue 691278 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Closed: Feb 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux
Pri: 2
Type: Bug-Security

Blocking:
issue 62400



Sign in to add a comment

heap-buffer-overflow in fx_codec_progress.cpp in CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback

Reported by joseph.b...@gmail.com, Feb 11 2017

Issue description

Steps to reproduce the problem:
1. Run pdf_codec_gif_fuzzer with either the original crash input or the minimized input.
2. Observe ASan report the heap-buffer-overflow.

Note that I was using Chromium commit has 27a8cfde871ad4786943a345569f36c9a5ba6e29 (Cr-Commit-Position: refs/heads/master@{#449073}), but there doesn't seem to be any changes to relevant files (as determined based on the ASan output) since that commit.

What is the expected behavior?
That pdf_codec_gif_fuzzer executes without ASan output.

What went wrong?
There was a heap-buffer-overflow detected with the inputs. The original crash input also causes ASan to detect a wild pointer.

Did this work before? N/A 

Chrome version: N/A  Channel: n/a
OS Version: 3.16.39-1 on Debian
Flash Version: N/A

=== Begin original ASan output ===
==7888==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000012310 at pc 0x000001f476b2 bp 0x7ffcf05e2b30 sp 0x7ffcf05e2b28
READ of size 4 at 0x602000012310 thread T0
    #0 0x1f476b1 in CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback(void*, unsigned int, FX_RECT const&, int, void*, int, bool, int, int, bool) third_party/pdfium/core/fxcodec/codec/fx_codec_progress.cpp:699:18
    #1 0x1f9e74a in gif_get_record_position(tag_gif_decompress_struct*, unsigned int, int, int, int, int, int, void*, int, bool, int, int, bool) third_party/pdfium/core/fxcodec/codec/fx_codec_gif.cpp:67:10
    #2 0x1fd0add in gif_load_frame(tag_gif_decompress_struct*, int) third_party/pdfium/core/fxcodec/lgif/fx_gif.cpp:872:19
    #3 0x1fa0006 in CCodec_GifModule::LoadFrame(FXGIF_Context*, int, CFX_DIBAttribute*) third_party/pdfium/core/fxcodec/codec/fx_codec_gif.cpp:146:17
    #4 0x1f6fd26 in CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause*) third_party/pdfium/core/fxcodec/codec/fx_codec_progress.cpp:2167:25
    #5 0x4fa1f4 in XFACodecFuzzer::Fuzz(unsigned char const*, unsigned long, FXCODEC_IMAGE_TYPE) third_party/pdfium/testing/libfuzzer/xfa_codec_fuzzer.h:36:25
    #6 0x534077 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) third_party/libFuzzer/src/FuzzerLoop.cpp:550:13
    #7 0x534ab2 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long) third_party/libFuzzer/src/FuzzerLoop.cpp:501:3
    #8 0x5388df in fuzzer::Fuzzer::MutateAndTestOne() third_party/libFuzzer/src/FuzzerLoop.cpp:757:30
    #9 0x539a07 in fuzzer::Fuzzer::Loop() third_party/libFuzzer/src/FuzzerLoop.cpp:791:5
    #10 0x506857 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) third_party/libFuzzer/src/FuzzerDriver.cpp:567:6
    #11 0x5425d9 in main third_party/libFuzzer/src/FuzzerMain.cpp:20:10
    #12 0x7f3458e002b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)

Address 0x602000012310 is a wild pointer.
SUMMARY: AddressSanitizer: heap-buffer-overflow third_party/pdfium/core/fxcodec/codec/fx_codec_progress.cpp:699:18 in CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback(void*, unsigned int, FX_RECT const&, int, void*, int, bool, int, int, bool)
Shadow bytes around the buggy address:
  0x0c047fffa410: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffa420: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffa430: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffa440: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffa450: fa fa fa fa fa fa 01 fa fa fa fa fa fa fa fa fa
=>0x0c047fffa460: fa fa[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffa470: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffa480: fa fa fa fa fa fa fa fa fa fa fa fa fa fa 00 fa
  0x0c047fffa490: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffa4a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffa4b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==7888==ABORTING
=== End original ASan output ===

=== Begin minimized ASan output ===
==8052==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000350 at pc 0x000001f476b2 bp 0x7ffde66f5710 sp 0x7ffde66f5708
READ of size 4 at 0x602000000350 thread T0
    #0 0x1f476b1 in CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback(void*, unsigned int, FX_RECT const&, int, void*, int, bool, int, int, bool) third_party/pdfium/core/fxcodec/codec/fx_codec_progress.cpp:699:18
    #1 0x1f9e74a in gif_get_record_position(tag_gif_decompress_struct*, unsigned int, int, int, int, int, int, void*, int, bool, int, int, bool) third_party/pdfium/core/fxcodec/codec/fx_codec_gif.cpp:67:10
    #2 0x1fd0add in gif_load_frame(tag_gif_decompress_struct*, int) third_party/pdfium/core/fxcodec/lgif/fx_gif.cpp:872:19
    #3 0x1fa0006 in CCodec_GifModule::LoadFrame(FXGIF_Context*, int, CFX_DIBAttribute*) third_party/pdfium/core/fxcodec/codec/fx_codec_gif.cpp:146:17
    #4 0x1f6fd26 in CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause*) third_party/pdfium/core/fxcodec/codec/fx_codec_progress.cpp:2167:25
    #5 0x4fa1f4 in XFACodecFuzzer::Fuzz(unsigned char const*, unsigned long, FXCODEC_IMAGE_TYPE) third_party/pdfium/testing/libfuzzer/xfa_codec_fuzzer.h:36:25
    #6 0x534077 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) third_party/libFuzzer/src/FuzzerLoop.cpp:550:13
    #7 0x534ab2 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long) third_party/libFuzzer/src/FuzzerLoop.cpp:501:3
    #8 0x4fe5b9 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) third_party/libFuzzer/src/FuzzerDriver.cpp:268:6
    #9 0x5050f9 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) third_party/libFuzzer/src/FuzzerDriver.cpp:517:9
    #10 0x5425d9 in main third_party/libFuzzer/src/FuzzerMain.cpp:20:10
    #11 0x7f64fb3a82b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)

0x602000000351 is located 0 bytes to the right of 1-byte region [0x602000000350,0x602000000351)
allocated by thread T0 here:
    #0 0x4cc9b3 in __interceptor_calloc (/home/joseph/fuzz/chromium/src/out/noassert2/pdf_codec_gif_fuzzer+0x4cc9b3)
    #1 0x1f45fce in FX_AllocOrDie third_party/pdfium/core/fxcrt/fx_memory.h:40:22
    #2 0x1f45fce in CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback(void*, unsigned int, FX_RECT const&, int, void*, int, bool, int, int, bool) third_party/pdfium/core/fxcodec/codec/fx_codec_progress.cpp:667
    #3 0x1f9e74a in gif_get_record_position(tag_gif_decompress_struct*, unsigned int, int, int, int, int, int, void*, int, bool, int, int, bool) third_party/pdfium/core/fxcodec/codec/fx_codec_gif.cpp:67:10
    #4 0x1fd0add in gif_load_frame(tag_gif_decompress_struct*, int) third_party/pdfium/core/fxcodec/lgif/fx_gif.cpp:872:19
    #5 0x1fa0006 in CCodec_GifModule::LoadFrame(FXGIF_Context*, int, CFX_DIBAttribute*) third_party/pdfium/core/fxcodec/codec/fx_codec_gif.cpp:146:17
    #6 0x1f6fd26 in CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause*) third_party/pdfium/core/fxcodec/codec/fx_codec_progress.cpp:2167:25
    #7 0x4fa1f4 in XFACodecFuzzer::Fuzz(unsigned char const*, unsigned long, FXCODEC_IMAGE_TYPE) third_party/pdfium/testing/libfuzzer/xfa_codec_fuzzer.h:36:25
    #8 0x534077 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) third_party/libFuzzer/src/FuzzerLoop.cpp:550:13
    #9 0x534ab2 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long) third_party/libFuzzer/src/FuzzerLoop.cpp:501:3
    #10 0x4fe5b9 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) third_party/libFuzzer/src/FuzzerDriver.cpp:268:6
    #11 0x5050f9 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) third_party/libFuzzer/src/FuzzerDriver.cpp:517:9
    #12 0x5425d9 in main third_party/libFuzzer/src/FuzzerMain.cpp:20:10
    #13 0x7f64fb3a82b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)

SUMMARY: AddressSanitizer: heap-buffer-overflow third_party/pdfium/core/fxcodec/codec/fx_codec_progress.cpp:699:18 in CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback(void*, unsigned int, FX_RECT const&, int, void*, int, bool, int, int, bool)
Shadow bytes around the buggy address:
  0x0c047fff8010: fa fa 03 fa fa fa 03 fa fa fa 01 fa fa fa 01 fa
  0x0c047fff8020: fa fa 03 fa fa fa 03 fa fa fa 02 fa fa fa 03 fa
  0x0c047fff8030: fa fa 00 00 fa fa 00 fa fa fa 00 fa fa fa 01 fa
  0x0c047fff8040: fa fa 01 fa fa fa 01 fa fa fa 01 fa fa fa 01 fa
  0x0c047fff8050: fa fa 04 fa fa fa 01 fa fa fa 01 fa fa fa 00 fa
=>0x0c047fff8060: fa fa 00 01 fa fa 00 fa fa fa[01]fa fa fa fa fa
  0x0c047fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff80a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff80b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==8052==ABORTING
=== End minimized ASan output ===

 
Note that I only have reproduced this with pdf_codec_gif_fuzzer, because the fuzzer works with gifs and chromium itself obviously won't trigger on the plain gif.
My args.gn may help in reproducing this:

pdf_enable_xfa = true
pdf_enable_v8 = true

is_asan = true
is_ubsan = true
enable_nacl = false
use_libfuzzer = true
is_debug = false
Oops, looks like the files never attached. Here they are.
crash-58fd6b9fc0646b7d0498b3d87170d88fb5fe9990
182 bytes View Download
minimized-from-b36acbfee872519238b0f408176f8c7b7831f893
26 bytes View Download
Project Member

Comment 4 by ClusterFuzz, Feb 11 2017

ClusterFuzz is analyzing your testcase. Developers can follow the progress at https://cluster-fuzz.appspot.com/testcase?key=6647413130657792
Project Member

Comment 5 by ClusterFuzz, Feb 12 2017

ClusterFuzz is analyzing your testcase. Developers can follow the progress at https://cluster-fuzz.appspot.com/testcase?key=5732543220678656
Looking at the original crashing input, we end up at the following line:

https://cs.chromium.org/chromium/src/third_party/pdfium/core/fxcodec/codec/fx_codec_progress.cpp?l=667&rcl=2eb1a705c243b2d5ab912268dd453f5ade075b6f

where FX_Alloc is called to allocate memory for m_pSrcPalette. The pal_num is zero there, but is used by a calloc call in FX_AllocOrDie as calloc's first parameter. So calloc may return NULL or a pointer and evidently it returns a pointer on my system. That is why the oob read occurs later on in that function.
This looks to me to be similar in some ways to CVE-2016-1681 (https://bugs.chromium.org/p/chromium/issues/detail?id=613160). However, I haven't yet demonstrated an oob write, nor do I have a PDF trigger. Suggestions for Linux tools for taking my GIF and making a PDF are welcome.
Is ClusterFuzz doing okay? Seems to be taking a long time.
Components: Internals>Plugins>PDF
Owner: och...@chromium.org
Status: Assigned (was: Unconfirmed)
+ochang@, could you take a look to see if this is related to https://bugs.chromium.org/p/chromium/issues/detail?id=613160?
I tried to reproduce with clustterFuzz, but somehow there was "Build setup failed." error. Maybe I didn't setup all the params right.
Blocking: 62400
Cc: dsinclair@chromium.org och...@chromium.org
Owner: npm@chromium.org
This XFA, which is not enabled on any branch of chrome.
Labels: Security_Severity-Low Security_Impact-None
Project Member

Comment 12 by ClusterFuzz, Feb 14 2017

ClusterFuzz is analyzing your testcase. Developers can follow the progress at https://cluster-fuzz.appspot.com/testcase?key=4903424681574400
Project Member

Comment 13 by ClusterFuzz, Feb 14 2017

ClusterFuzz is analyzing your testcase. Developers can follow the progress at https://cluster-fuzz.appspot.com/testcase?key=5672020890353664
Project Member

Comment 14 by ClusterFuzz, Feb 14 2017

Detailed report: https://cluster-fuzz.appspot.com/testcase?key=5672020890353664

Fuzzer: pdf_codec_gif_fuzzer
Job Type: libfuzzer_chrome_asan
Crash Type: Heap-buffer-overflow READ 4
Crash Address: 0x609000000a70
Crash State:
  CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback
  gif_get_record_position
  gif_load_frame
  
Sanitizer: address (ASAN)

Recommended Security Severity: Medium

Regressed: https://cluster-fuzz.appspot.com/revisions?job=libfuzzer_chrome_asan&range=400757:400887

Reproducer Testcase: https://cluster-fuzz.appspot.com/download/AMIfv95iN7Xx3K3n4kwH_CkrMWP4L6_Ih-fK7fb-F4IynyOFP3DPlQM6ShdNhQ3FsqWtNX93nuW_AmBOE31BLCbAMGM8ARmYF31uMNpbn295RqNlNepAQ9hsSWS1In1zrUHbgCXKCiyBJhNG3CnbrvEDgqAy_L1V4zSAlMjN4jaI9F0wiWwQTJHvp75OhIQAkbvGEZNltf-nqsILjyYUolHq0C787z977vHoo1P4-W2buGVEMfH8EdH5dSp-23pKVCJOc-BZT35kBVyAgmGgb3o1ekTUd17WwtaPElvhAch2k8-NJt3DWsxyFdH2FyEzwwx7Z1BG5KGyFkzWjwr51IV8eCY0DxxBiBJlUaY3JpI-4HkqUYt3CZP9eCCdm5ikVH7jdXQto8DDVHBQHUj30E5ResYBv9y-6w?testcase_id=5672020890353664


See https://chromium.googlesource.com/chromium/src/+/master/testing/libfuzzer/reproducing.md for more information.

The recommended severity is different from what was assigned to the bug. Please double check the accuracy of the assigned severity.

Comment 15 by npm@chromium.org, Feb 15 2017

Status: Fixed (was: Assigned)
I don't know why bugdroid sometimes doesn't pick up my CLs...
https://pdfium-review.googlesource.com/c/2699/
Project Member

Comment 16 by ClusterFuzz, Feb 15 2017

ClusterFuzz has detected this issue as fixed in range 450434:450482.

Detailed report: https://cluster-fuzz.appspot.com/testcase?key=5672020890353664

Fuzzer: pdf_codec_gif_fuzzer
Job Type: libfuzzer_chrome_asan
Crash Type: Heap-buffer-overflow READ 4
Crash Address: 0x609000000a70
Crash State:
  CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback
  gif_get_record_position
  gif_load_frame
  
Sanitizer: address (ASAN)

Recommended Security Severity: Medium

Regressed: https://cluster-fuzz.appspot.com/revisions?job=libfuzzer_chrome_asan&range=400757:400887
Fixed: https://cluster-fuzz.appspot.com/revisions?job=libfuzzer_chrome_asan&range=450434:450482

Reproducer Testcase: https://cluster-fuzz.appspot.com/download/AMIfv95iN7Xx3K3n4kwH_CkrMWP4L6_Ih-fK7fb-F4IynyOFP3DPlQM6ShdNhQ3FsqWtNX93nuW_AmBOE31BLCbAMGM8ARmYF31uMNpbn295RqNlNepAQ9hsSWS1In1zrUHbgCXKCiyBJhNG3CnbrvEDgqAy_L1V4zSAlMjN4jaI9F0wiWwQTJHvp75OhIQAkbvGEZNltf-nqsILjyYUolHq0C787z977vHoo1P4-W2buGVEMfH8EdH5dSp-23pKVCJOc-BZT35kBVyAgmGgb3o1ekTUd17WwtaPElvhAch2k8-NJt3DWsxyFdH2FyEzwwx7Z1BG5KGyFkzWjwr51IV8eCY0DxxBiBJlUaY3JpI-4HkqUYt3CZP9eCCdm5ikVH7jdXQto8DDVHBQHUj30E5ResYBv9y-6w?testcase_id=5672020890353664


See https://chromium.googlesource.com/chromium/src/+/master/testing/libfuzzer/reproducing.md for more information.

If you suspect that the result above is incorrect, try re-doing that job on the test case report page.
Project Member

Comment 17 by sheriffbot@chromium.org, Feb 16 2017

Labels: -Restrict-View-SecurityTeam Restrict-View-SecurityNotify
Project Member

Comment 18 by sheriffbot@chromium.org, May 25 2017

Labels: -Restrict-View-SecurityNotify allpublic
This bug has been closed for more than 14 weeks. Removing security view restrictions.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot

Sign in to add a comment