New issue
Advanced search Search tips

Issue 633208 link

Starred by 3 users

Issue metadata

Status: Fixed
Owner:
Closed: Sep 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: ----
Type: Bug



Sign in to add a comment

PDFium Integer Overflow Vulnerability

Reported by stackexp...@gmail.com, Aug 1 2016

Issue description

VULNERABILITY DETAILS
If compile pdfium_test with UBSAN, the following error message will be throwed.

../../core/fxcodec/codec/fx_codec_jpx_opj.cpp:234:18: runtime error: shift exponent 127 is too large for 32-bit type 'int'
../../core/fxcodec/codec/fx_codec_jpx_opj.cpp:235:16: runtime error: shift exponent 128 is too large for 32-bit type 'int'
../../core/fxcodec/codec/fx_codec_jpx_opj.cpp:268:32: runtime error: load of null pointer of type 'const int'

The vulnerability lies in function |sycc422_to_rgb| of file fx_codec_jpx_opj.cpp.

static void sycc422_to_rgb(opj_image_t* img) {
  if (!sycc422_size_is_valid(img))
    return;

  int prec = img->comps[0].prec;    // 0x80
  int offset = 1 << (prec - 1);     // 1 << 0x7F, integer overflow
  int upb = (1 << prec) - 1;        // 1 << 0x80, integer overflow

  OPJ_UINT32 maxw = img->comps[0].w;
  OPJ_UINT32 maxh = img->comps[0].h;
  FX_SAFE_SIZE_T max_size = maxw;
  max_size *= maxh;
  if (!max_size.IsValid())
    return;

  const int* y = img->comps[0].data;
  const int* cb = img->comps[1].data;
  const int* cr = img->comps[2].data;
  int *d0, *d1, *d2, *r, *g, *b;
  d0 = r = FX_Alloc(int, max_size.ValueOrDie());
  d1 = g = FX_Alloc(int, max_size.ValueOrDie());
  d2 = b = FX_Alloc(int, max_size.ValueOrDie());
  for (uint32_t i = 0; i < maxh; ++i) {
    OPJ_UINT32 j;
    for (j = 0; j < (maxw & ~static_cast<OPJ_UINT32>(1)); j += 2) {
      sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
      ++y;
      ++r;
      ++g;
      ++b;
      sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
      ++y;
      ++r;
      ++g;
      ++b;
      ++cb;
      ++cr;
    }
    if (j < maxw) {
      sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
      ++y;
      ++r;
      ++g;
      ++b;
      ++cb;
      ++cr;
    }
  }
  FX_Free(img->comps[0].data);
  img->comps[0].data = d0;
  FX_Free(img->comps[1].data);
  img->comps[1].data = d1;
  FX_Free(img->comps[2].data);
  img->comps[2].data = d2;
  img->comps[1].w = maxw;
  img->comps[1].h = maxh;
  img->comps[2].w = maxw;
  img->comps[2].h = maxh;
  img->comps[1].dx = img->comps[0].dx;
  img->comps[2].dx = img->comps[0].dx;
  img->comps[1].dy = img->comps[0].dy;
  img->comps[2].dy = img->comps[0].dy;
}


This issue was caused by the malformed JPEG2000 image. The content of the malformed image can be represented as follows (in hex mode).

00 00 00 0C 6A 50 20 20 0D 0A 87 0A 00 00 00 14
66 74 79 70 55 70 32 20 00 00 00 00 6A 70 32 20
00 00 00 2D 6A 70 32 68 00 00 00 16 69 68 64 72
00 00 00 14 00 00 00 14 00 01 07 07 00 00 00 00
00 0F 63 6F 6C 72 01 00 00 00 00 00 10 00 00 00
00 6A 70 32 63 FF 4F FF 51 00 2F 00 00 00 00 00
01 FF F6 00 01 00 00 00 00 EF FF FF FF 00 00 00
02 F0 00 01 00 00 00 00 00 00 00 00 00 00 [03 FF
01 01 80 02 01 0F 02 01] FF 52 00 0C 00 00 00 01
00 1C 05 03 00 01 FF 5C 00 13 20 40 48 48 50 48
48 50 48 48 50 48 48 50 48 48 50 FF 5F 00 10 00
EA 00 01 4B 01 02 00 01 00 01 06 03 05 FF 90 00
0A 00 00 00 00 00 00 6E 98 80 14

In the SIZ (0xFF51) block, the number of components was 0x03 and the data for these components were:
FF 01 01
80 02 01
0F 02 01

Here 0xFF was used to compute the value of variable |prec|. The code lies in function |opj_j2k_read_siz| of file j2k.c.

        for (i = 0; i < l_image->numcomps; ++i){
                OPJ_UINT32 tmp;
                opj_read_bytes(p_header_data,&tmp,1);   /* Ssiz_i */
                ++p_header_data;
                l_img_comp->prec = (tmp & 0x7f) + 1;    // -------------------------> tmp == 0xFF, prec = (0xFF & 0x7F) + 1 = 0x80
                l_img_comp->sgnd = tmp >> 7;
                opj_read_bytes(p_header_data,&tmp,1);   /* XRsiz_i */
                ++p_header_data;
                l_img_comp->dx = (OPJ_UINT32)tmp; /* should be between 1 and 255 */
                opj_read_bytes(p_header_data,&tmp,1);   /* YRsiz_i */
                ++p_header_data;
                l_img_comp->dy = (OPJ_UINT32)tmp; /* should be between 1 and 255 */
                if( l_img_comp->dx < 1 || l_img_comp->dx > 255 ||
                    l_img_comp->dy < 1 || l_img_comp->dy > 255 ) {
                    opj_event_msg(p_manager, EVT_ERROR,
                                  "Invalid values for comp = %d : dx=%u dy=%u\n (should be between 1 and 255 according the JPEG2000 norm)",
                                  i, l_img_comp->dx, l_img_comp->dy);
                    return OPJ_FALSE;
                }

VERSION
Chrome Version: [x.x.x.x] + [stable, beta, or dev]
Operating System: [Please indicate OS, version, and service pack level]

REPRODUCTION CASE
Please include a demonstration of the security bug, such as an attached
HTML or binary file that reproduces the bug when loaded in Chrome. PLEASE
make the file as small as possible and remove any content not required to
demonstrate the bug.

FOR CRASHES, PLEASE INCLUDE THE FOLLOWING ADDITIONAL INFORMATION
Type of crash: [tab, browser, etc.]
Crash State: [see link above: stack trace, registers, exception record]
Client ID (if relevant): [see link above]

 
poc.pdf
1.1 KB Download
I'm not sure whether this issue has security impact or not. If you think it's not a security issue, feel free to remove the Bug-Security label and add a normal bug label.

Also, the proof-of-concept file can trigger a null pointer deference problem. But that's not a security issue.
Project Member

Comment 2 by ClusterFuzz, Aug 1 2016

ClusterFuzz is analyzing your testcase. Developers can follow the progress at https://cluster-fuzz.appspot.com/testcase?key=6312423965589504
Components: Internals>Plugins>PDF
Labels: -Type-Bug-Security -Restrict-View-SecurityTeam OS-All Type-Bug
Owner: tsepez@chromium.org
Status: Assigned (was: Unconfirmed)
Summary: PDFium Integer Overflow Vulnerability (was: Security: PDFium Integer Overflow Vulnerability)
Marking as non-security since the resulting values are only used as color values. Mind routing this to the right folks, tsepez@?
Cc: dsinclair@chromium.org
Owner: och...@chromium.org
@rickyz - feel free to assign these to dsinclair@ or ochang@
Cc: -dsinclair@chromium.org och...@chromium.org
Owner: dsinclair@chromium.org
Punting to dsinclair.
Status: Started (was: Assigned)
Project Member

Comment 8 by bugdroid1@chromium.org, Sep 12 2016

The following revision refers to this bug:
  https://pdfium.googlesource.com/pdfium.git/+/db319ec6a9330e75276b873f6027caddf2a15ec0

commit db319ec6a9330e75276b873f6027caddf2a15ec0
Author: dsinclair <dsinclair@chromium.org>
Date: Mon Sep 12 21:04:08 2016

Verify value of prec before using

The fx_codec_jpx_opj code will attempt to do a 1 << (prec - 1). If the prec
value is >=32 then that shift will overflow the int value. This CL adds a check
that prec is < 32 before attempting the shift.

BUG= chromium:633208 

Review-Url: https://codereview.chromium.org/2334823002

[modify] https://crrev.com/db319ec6a9330e75276b873f6027caddf2a15ec0/core/fxcodec/codec/fx_codec_jpx_opj.cpp

Status: Fixed (was: Started)
Project Member

Comment 10 by bugdroid1@chromium.org, Sep 12 2016

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/7d8fc6b4365fa14e80b83213fa7ea5f77fd43f9b

commit 7d8fc6b4365fa14e80b83213fa7ea5f77fd43f9b
Author: pdfium-deps-roller <pdfium-deps-roller@chromium.org>
Date: Mon Sep 12 23:34:13 2016

Roll src/third_party/pdfium/ 01b67ed9b..9de00fdc4 (4 commits).

https://pdfium.googlesource.com/pdfium.git/+log/01b67ed9b441..9de00fdc4d4e

$ git log 01b67ed9b..9de00fdc4 --date=short --no-merges --format='%ad %ae %s'
2016-09-12 weili Fix some leaks associated with memory allocator
2016-09-12 weili Fix leaked value object in NamedPropertySetterCallback()
2016-09-12 npm Remove GetDictBy("DR") from annot/field dictionaries
2016-09-12 dsinclair Verify value of prec before using

BUG= 633208 

TBR=dsinclair@chromium.org

Review-Url: https://codereview.chromium.org/2334923002
Cr-Commit-Position: refs/heads/master@{#418104}

[modify] https://crrev.com/7d8fc6b4365fa14e80b83213fa7ea5f77fd43f9b/DEPS

Project Member

Comment 11 by ClusterFuzz, Sep 13 2016

ClusterFuzz has detected this issue as fixed in range 418041:418137.

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

Job Type: linux_asan_pdfium
Platform Id: linux

Crash Type: UNKNOWN READ
Crash Address: 0x000000000000
Crash State:
  color_sycc_to_rgb
  CJPX_Decoder::Init
  CCodec_JpxModule::CreateDecoder
  
Regressed: https://cluster-fuzz.appspot.com/revisions?job=linux_asan_pdfium&range=353893:353966
Fixed: https://cluster-fuzz.appspot.com/revisions?job=linux_asan_pdfium&range=418041:418137

Minimized Testcase (1.12 Kb): https://cluster-fuzz.appspot.com/download/AMIfv975jkZdzDUA6f6j5KRGMTpDzjT7232RYKrjnLBpm1fd3bp9Uezw145uxYo1j9rU12Zz4_JdBed2ntQlTYB8ZBy7pIFk8aL3338j1bAj0P-oZ64zPnT54xYVf5_H_ZVuECKoA0oDGfCm4DmJZGRLoK6Y-HvUwg?testcase_id=6312423965589504

See https://dev.chromium.org/Home/chromium-security/bugs/reproducing-clusterfuzz-bugs for more information.

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

Sign in to add a comment