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)
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)
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
Updated•13 years ago
|
Flags: sec-bounty?
Updated•13 years ago
|
Whiteboard: [asan]
Comment 1•13 years ago
|
||
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
Comment 2•13 years ago
|
||
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).
Comment 3•13 years ago
|
||
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.
| Reporter | ||
Comment 4•13 years ago
|
||
(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.
Comment 5•13 years ago
|
||
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?
Comment 7•13 years ago
|
||
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.
Comment 10•13 years ago
|
||
Right, the "while()" continues if the unsigned "c" gets decremented past zero.
Comment 11•13 years ago
|
||
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.
Comment 12•13 years ago
|
||
(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.
Comment 13•13 years ago
|
||
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.
Comment 14•13 years ago
|
||
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.
| Reporter | ||
Comment 15•13 years ago
|
||
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);
Comment 16•13 years ago
|
||
Additional test file, without any PAETH filtering. Does this also exhibit the bug?
| Reporter | ||
Comment 17•13 years ago
|
||
(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.
Comment 18•13 years ago
|
||
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).
| Reporter | ||
Comment 19•13 years ago
|
||
(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
Comment 20•13 years ago
|
||
Does Firefox, built with "clang -O2" but without asan, exhibit a problem?
Assignee: glennrp+bmo → nobody
Comment 21•13 years ago
|
||
Also, can you verify that the bug still exists if you drop back to clang-3.2?
| Reporter | ||
Comment 22•13 years ago
|
||
(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.
Comment 23•13 years ago
|
||
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.
Updated•13 years ago
|
Status: ASSIGNED → NEW
Comment 24•13 years ago
|
||
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?
Comment 26•13 years ago
|
||
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
Comment 27•13 years ago
|
||
(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
Comment 30•13 years ago
|
||
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.
status-b2g18:
--- → unaffected
status-firefox-esr17:
--- → unaffected
Comment 31•13 years ago
|
||
Compiler bugs are generally out of scope for the bounty.
Flags: sec-bounty? → sec-bounty-
Keywords: sec-high → sec-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?
Comment 32•13 years ago
|
||
Out-of-bounds *write*, wasn't it? Some of the "fa" bytes were overwritten.
Updated•10 years ago
|
Group: core-security → core-security-release
Updated•9 years ago
|
Group: core-security-release
Updated•1 year ago
|
Keywords: reporter-external
You need to log in
before you can comment on or make changes to this bug.
Description
•