Closed Bug 824536 Opened 13 years ago Closed 13 years ago

Out of bound read in MOZ_PNG_combine_row

Categories

(Core :: Graphics: ImageLib, defect)

x86_64
All
defect
Not set
normal

Tracking

()

RESOLVED FIXED
Tracking Status
firefox-esr17 --- unaffected
b2g18 --- unaffected

People

(Reporter: inferno, Unassigned)

Details

(Keywords: reporter-external, sec-vector, Whiteboard: [asan] clang optimization bug?)

Attachments

(2 files)

Attached image Testcase png
Reproduces on trunk. Set env as ASAN_OPTIONS=redzone=64 ==13004== ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7f42ff7aea00 at pc 0x7f4326209ef4 bp 0x7fff66de8040 sp 0x7fff66de8038 READ of size 1 at 0x7f42ff7aea00 thread T0 #0 0x7f4326209ef3 in MOZ_PNG_combine_row src/media/libpng/pngrutil.c:3361 0x7f42ff7aea00 is located 64 bytes to the left of 343-byte region [0x7f42ff7aea40,0x7f42ff7aeb97) allocated by thread T0 here: #0 0x411312 in malloc #1 0x7f43261f6d17 in MOZ_PNG_malloc src/media/libpng/pngmem.c:562 #2 0x7f43261f6d17 in MOZ_PNG_calloc src/media/libpng/pngmem.c:489 Shadow bytes around the buggy address: 0x1fe85fef5cf0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x1fe85fef5d00: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd 0x1fe85fef5d10: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x1fe85fef5d20: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa 0x1fe85fef5d30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa =>0x1fe85fef5d40:[fa]fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 0x1fe85fef5d50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1fe85fef5d60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1fe85fef5d70: 00 00 07 fb fb fb fb fb fa fa fa fa fa fa fa fa 0x1fe85fef5d80: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 0x1fe85fef5d90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 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 Heap righ redzone: fb Freed Heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 ASan internal: fe Stats: 94M malloced (101M for red zones) by 344880 calls Stats: 4M realloced by 18831 calls Stats: 59M freed by 205183 calls Stats: 26M really freed by 112327 calls Stats: 148M (148M-0M) mmaped; 291 maps, 0 unmaps mmaps by size class: 7:180180; 8:57316; 9:11253; 10:6643; 11:5100; 12:1664; 13:832; 14:384; 15:208; 16:728; 17:68; 18:14; 19:5; 20:4; mallocs by size class: 7:240965; 8:71596; 9:13130; 10:7902; 11:6252; 12:1906; 13:1128; 14:537; 15:243; 16:1118; 17:78; 18:16; 19:5; 20:4; frees by size class: 7:146843; 8:40627; 9:6327; 10:4427; 11:3883; 12:900; 13:839; 14:384; 15:132; 16:742; 17:67; 18:8; 19:2; 20:2; rfrees by size class: 7:88714; 8:16641; 9:2523; 10:1689; 11:1479; 12:278; 13:349; 14:183; 15:41; 16:417; 17:10; 18:3; Stats: malloc large: 1464 small slow: 3185 ==13004== ABORTING
Component: General → ImageLib
Product: Firefox → Core
Whiteboard: [asan]
The report doesn't say but it looks as though (because of the MOZ_ prefixes) reporter was using the bundled libpng. pngcrush indicates that the image is an interlaced PNG with only IHDR, IDAT, and IEND chunks.
Assignee: nobody → glennrp+bmo
Status: NEW → ASSIGNED
pngcheck doesn't show anything interesting about the file: pngcheck -v -v test.png File: testff.png (231 bytes) chunk IHDR at offset 0x0000c, length 13 45 x 45 image, 24-bit RGB, interlaced chunk IDAT at offset 0x00025, length 174 zlib: deflated, 32K window, maximum compression rows per pass: 6, 6, 6, 12, 11, 23, 22 row filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth): 1 2 4 2 4 2 | 1 2 4 2 4 2 | 1 2 4 2 4 2 | 1 2 2 2 4 2 2 2 4 2 2 2 | 1 2 2 2 4 2 2 4 2 2 2 | 1 2 2 2 2 2 2 2 4 2 2 2 2 2 2 4 2 2 2 2 2 2 2 | 1 2 2 2 2 2 2 4 2 2 2 2 2 2 2 4 2 2 2 2 2 2 (86 out of 86) chunk IEND at offset 0x000df, length 0 No errors detected in test.png (3 chunks, 96.2% compression).
Line 3361 of pngrutil.c is in a block of code that was revised in libpng-1.5.6 to handle aligned memory. Someone please try putting "#define PNG_ALIGN_TYPE 0" in mozpngconf.h and see if the problem still exists.
(In reply to Glenn Randers-Pehrson from comment #1) > The report doesn't say but it looks as though (because of the MOZ_ prefixes) > reporter was using the bundled libpng. pngcrush indicates that the image is > an interlaced PNG with only IHDR, IDAT, and IEND chunks. Yes, i am using firefox's bundled libpng. Also, is evident from the src location in crash stack - src/media/libpng/pngrutil.c:3361 (In reply to Glenn Randers-Pehrson from comment #3) > Line 3361 of pngrutil.c is in a block of code that was revised in > libpng-1.5.6 to handle aligned memory. Someone please try putting "#define > PNG_ALIGN_TYPE 0" in > mozpngconf.h and see if the problem still exists. Adding "#define PNG_ALIGN_TYPE 0" fixes the crash.
Thank you. Please try changing the two "while" statements to the following: line 3343: while (c >= sizeof(png_uint_32)); and line 3384: while (c >= sizeof(png_uint_16)); (and remove the "#define PNG_ALIGN_TYPE 0"). If that works I'll prepare a proper patch, and apply it to upstream libpng as well.
(In reply to Glenn Randers-Pehrson from comment #5) > Thank you. Please try changing the two "while" > statements to the following: I'm looking at the 1.5.13 sources, and I don't see anything matching this?
In libpng-1.5.13 the lines are 3165 and 3206. Both are while (c > 0); In the mozilla embedded libpng they are pushed down by a couple hundred lines of APNG supporting code.
Oh, I get the point now: if the number of bytes to copy isn't a multiple of the copy-word size, you copy one full word too many. Ooops.
Oh, no, scratch that --- c is size_t, so the test is effectively (c != 0). So it'll loop till core dump. Ugh.
Right, the "while()" continues if the unsigned "c" gets decremented past zero.
Libpng-1.5.14 is due out on January 24th. libpng-1.5.14rc01 will be out on the 10th, without the patch. I'll apply the patch to libpng-1.5.14 as it's released, so I suggest that this bug be held private until the 24th. I'm assuming that the patch I described in comment #5 will fix the problem.
(In reply to Glenn Randers-Pehrson from comment #10) > Right, the "while()" continues if the unsigned "c" gets decremented past zero. But wait --- doesn't the initial alignment test prevent that case? I went through the code again, and I don't see where it's not an accurate reimplementation of the memcpy version.
I am told that the "while" statements are OK, due to the intial checking. Instead, the problem seems to be a failure to decrement row_width. We need to insert row_width-=sizeof(png_uint_32); and row_width-=sizeof(png_uint_16); inside the two while() loops, respectively.
I've been unable to reproduce the buggy behavior with libpng-1.5.13 in another application (ImageMagick, modified to use the "blocky" de-interlacing), running under Ubuntu on a 64-bit workstation. Debug printout shows there's no runaway "while" loop when decoding the test image.
Based on last comments, I did the patch, but it does not fix the problem. diff -r 6955309291ee media/libpng/pngrutil.c --- a/media/libpng/pngrutil.c Wed Jan 02 19:35:43 2013 -0800 +++ b/media/libpng/pngrutil.c Thu Jan 03 18:11:11 2013 -0800 @@ -3339,6 +3339,7 @@ { *dp32++ = *sp32++; c -= sizeof (png_uint_32); + row_width -= sizeof(png_uint_32); } while (c > 0); @@ -3380,6 +3381,7 @@ { *dp16++ = *sp16++; c -= sizeof (png_uint_16); + row_width -= sizeof(png_uint_16); } while (c > 0);
Additional test file, without any PAETH filtering. Does this also exhibit the bug?
(In reply to Glenn Randers-Pehrson from comment #16) > Created attachment 697782 [details] > Test file, without PAETH filtering > > Additional test file, without any PAETH filtering. Does this also exhibit > the bug? Yes, this testcase also crashes.
I'm not seeing this bug with the installed Firefox 17.0.1 on my 64-bit Ubuntu platform, nor with the current "nightly" distribution of Firefox 20.0a1 (2013-01-04). I'm running out of ideas. Should we check in a patch to "#define PNG_ALIGN_TYPE 0" in mozpngconf.h to work around the bug (with perhaps a performance penalty) temporarily? A libpng developer suggests maybe it's an optimization problem (try building with pngrutil.c compiled without optimization).
(In reply to Glenn Randers-Pehrson from comment #18) > I'm not seeing this bug with the installed Firefox 17.0.1 on my 64-bit > Ubuntu platform, nor with the current "nightly" distribution of Firefox > 20.0a1 (2013-01-04). I'm running out of ideas. Should we check in a patch > to "#define PNG_ALIGN_TYPE 0" in mozpngconf.h to work around the bug (with > perhaps a performance penalty) temporarily? This is Mozilla's security team decision. > > A libpng developer suggests maybe it's an optimization problem (try building > with pngrutil.c compiled without optimization). I does look like it. The bug only reproduces in clang -O2 optimization, but does not reproduce with -O1. Steps to build ASAN here https://developer.mozilla.org/en-US/docs/Building_Firefox_with_Address_Sanitizer, clang revision i am using is 171202
Does Firefox, built with "clang -O2" but without asan, exhibit a problem?
Assignee: glennrp+bmo → nobody
Also, can you verify that the bug still exists if you drop back to clang-3.2?
(In reply to Glenn Randers-Pehrson from comment #20) > Does Firefox, built with "clang -O2" but without asan, exhibit a problem? This is filed as a security vulnerability, so it does not matter whether it reproduces as a crash in a regular clang build. Many of the OOB reads/writes won't crash in a regular build, but they still matter because of the security implications.
At this point there is no very good reason to believe there is any libpng bug here at all --- what seems substantially more likely is that we're looking at a code-generation bug in clang 3.3. The argument in comment #22 is therefore off-point.
Status: ASSIGNED → NEW
Rafael, could you possibly look into this a little to evaluate whether it is a Clang problem, and file a bug or whatever as appropriate? Thanks.
(In reply to Andrew McCreight [:mccr8] from comment #24) > Rafael, could you possibly look into this a little to evaluate whether it is > a Clang problem, and file a bug or whatever as appropriate? Thanks. I can try. If I understand this correctly, it only reproduces with an asan build using clang trunk. Is that correct? Is this linux or OS X? You suspect a clang bug because a png bug would manifest in an infinite loop writing to memory, not just an off by one access, correct? Taras, what do you consider the relative priority of this bug to be?
Marking the sec-high. This would normally be sec-critical, but it's mitigated by the fact that we think it only happens with a compiler we don't normally use (if I understand correctly).
Keywords: sec-high
(In reply to Josh Aas (Mozilla Corporation) from comment #26) > Marking the sec-high. This would normally be sec-critical, but it's > mitigated by the fact that we think it only happens with a compiler we don't > normally use (if I understand correctly). Rafael, it's high priority to determine if this is a clang bug and if we should take steps to mitigate this if this may cause problems in (non-asan) mac builds
I cannot reproduce this. I have built clang 171202 and used that to build firefox on linux x86-64 using browser/config/mozconfigs/linux64/nightly-asan. I then ran ASAN_OPTIONS=redzone=64,alloc_dealloc_mismatch=0 ./obj-x86_64-unknown-linux-gnu/dist/bin/firefox I can then open both png files in this bug without crashing. I have built mozilla-central revision 1eab3e0d7f53.
Abhishek tells me this doesn't reproduce with clang 174592. It might have been fixed or at least the bug is hidden for now.
Status: NEW → RESOLVED
Closed: 13 years ago
Resolution: --- → FIXED
We don't ship ESR-17 or b2g18 releases built with clang so we don't need to update any of our toolchains for those branches.
Compiler bugs are generally out of scope for the bounty.
Flags: sec-bounty? → sec-bounty-
Keywords: sec-highsec-vector
Summary: Heap-buffer-overflow in MOZ_PNG_combine_row → Out of bound read in MOZ_PNG_combine_row
Whiteboard: [asan] → [asan] clang optimization bug?
Out-of-bounds *write*, wasn't it? Some of the "fa" bytes were overwritten.
Group: core-security → core-security-release
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: