Closed Bug 1224291 Opened 4 years ago Closed 4 years ago

ASan memcpy-param-overlap in Brotli’s “memmove16” (e.g. opening engadget.com)

Categories

(Core :: Graphics: Text, defect)

35 Branch
defect
Not set

Tracking

()

RESOLVED FIXED
mozilla47
Tracking Status
firefox45 --- fixed
firefox46 --- fixed
firefox47 --- fixed

People

(Reporter: vlad, Assigned: mcmanus)

References

Details

Attachments

(1 file)

Opening engadget.com, I get:

==9378==ERROR: AddressSanitizer: memcpy-param-overlap: memory ranges [0x62d000a96406,0x62d000a96416) and [0x62d000a96402, 0x62d000a96412) overlap
    #0 0x4adb1c in __asan_memcpy (/home/vladimir/proj/moz/fx-asan-od/dist/bin/plugin-container+0x4adb1c)
--DOCSHELL 0x61a0002d0c80 == 9 [pid = 9293] [id = 10]
    #1 0x7f871fc9b246 in memmove16 /home/vladimir/proj/moz/mc-hg/modules/brotli/dec/decode.c:112:3
    #2 0x7f871fc9312a in BrotliDecompressStreaming /home/vladimir/proj/moz/mc-hg/modules/brotli/dec/decode.c:1557:11
    #3 0x7f871fc8d4d9 in BrotliDecompress /home/vladimir/proj/moz/mc-hg/modules/brotli/dec/decode.c:982:12
    #4 0x7f871fc8d03e in BrotliDecompressBuffer /home/vladimir/proj/moz/mc-hg/modules/brotli/dec/decode.c:973:26
    #5 0x7f871fc826d4 in ots::ConvertWOFF2ToSFNT(ots::Font*, unsigned char*, unsigned long, unsigned char const*, unsigned long) /home/vladimir/proj/moz/mc-hg/gfx/ots/src/woff2.cc:1022:8
    #6 0x7f871fc67491 in (anonymous namespace)::ProcessWOFF2(ots::OpenTypeFile*, ots::Font*, ots::OTSStream*, unsigned char const*, unsigned long) /home/vladimir/proj/moz/mc-hg/gfx/ots/src/ots.cc:480:8
    #7 0x7f871fc67491 in ots::OTSContext::Process(ots::OTSStream*, unsigned char const*, unsigned long, unsigned int) /home/vladimir/proj/moz/mc-hg/gfx/ots/src/ots.cc:888
    #8 0x7f8719a7a408 in gfxUserFontEntry::SanitizeOpenTypeData(unsigned char const*, unsigned int, unsigned int&, gfxUserFontType) /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxUserFontSet.cpp:243:9
    #9 0x7f8719a7dd3d in gfxUserFontEntry::LoadPlatformFont(unsigned char const*, unsigned int&) /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxUserFontSet.cpp:594:9
    #10 0x7f8719a7b7a8 in gfxUserFontEntry::LoadNextSrc() /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxUserFontSet.cpp:484:29
    #11 0x7f8719a74478 in gfxUserFontEntry::Load() /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxUserFontSet.cpp:676:9
    #12 0x7f8719a74478 in gfxFontGroup::GetFirstValidFont(unsigned int) /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxTextRun.cpp:1863
    #13 0x7f8719a74d6e in gfxFontGroup::MakeHyphenTextRun(gfxContext*, unsigned int) /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxTextRun.cpp:2005:21
    #14 0x7f8719a75104 in gfxFontGroup::GetHyphenWidth(gfxTextRun::PropertyProvider*) /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxTextRun.cpp:2023:25
    #15 0x7f871df0eabb in PropertyProvider::GetHyphenWidth() /home/vladimir/proj/moz/mc-hg/layout/generic/nsTextFrame.cpp:3370:20
    #16 0x7f871df372df in nsTextFrame::ReflowText(nsLineLayout&, int, nsRenderingContext*, nsHTMLReflowMetrics&, unsigned int&) /home/vladimir/proj/moz/mc-hg/layout/generic/nsTextFrame.cpp:8772:37
    #17 0x7f871dc8e988 in nsLineLayout::ReflowFrame(nsIFrame*, unsigned int&, nsHTMLReflowMetrics*, bool&) /home/vladimir/proj/moz/mc-hg/layout/generic/nsLineLayout.cpp:945:31
    #18 0x7f871dcff3a3 in nsBlockFrame::ReflowInlineFrame(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, nsIFrame*, LineReflowStatus*) /home/vladimir/proj/moz/mc-hg/layout/generic/nsBlockFrame.cpp:4037:3
    #19 0x7f871dcfd9e3 in nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, nsFlowAreaRect&, int&, nsFloatManager::SavedState*, bool*, LineReflowStatus*, bool) /home/vladimir/proj/moz/mc-hg/layout/generic/nsBlockFrame.cpp:3839:5
    #20 0x7f871dcf264a in nsBlockFrame::ReflowInlineFrames(nsBlockReflowState&, nsLineList_iterator, bool*) /home/vladimir/proj/moz/mc-hg/layout/generic/nsBlockFrame.cpp:3705:9
    #21 0x7f871dcea778 in nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, bool*) /home/vladimir/proj/moz/mc-hg/layout/generic/nsBlockFrame.cpp:2714:5
    #22 0x7f871dcdf4ce in nsBlockFrame::ReflowDirtyLines(nsBlockReflowState&) /home/vladimir/proj/moz/mc-hg/layout/generic/nsBlockFrame.cpp:2249:7
    #23 0x7f871dcd75e6 in nsBlockFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) /home/vladimir/proj/moz/mc-hg/layout/generic/nsBlockFrame.cpp:1160:3
    #24 0x7f871dd4f818 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, mozilla::WritingMode const&, mozilla::LogicalPoint const&, nsSize const&, unsigned int, unsigned int&, nsOverflowContinuationTracker*) /home/vladimir/proj/moz/mc-hg/layout/generic/nsContainerFrame.cpp:996:3
    #25 0x7f871dde27d8 in nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState*, bool, bool, nsHTMLReflowMetrics*, bool) /home/vladimir/proj/moz/mc-hg/layout/generic/nsGfxScrollFrame.cpp:527:3
    #26 0x7f871dde43ef in nsHTMLScrollFrame::ReflowContents(ScrollReflowState*, nsHTMLReflowMetrics const&) /home/vladimir/proj/moz/mc-hg/layout/generic/nsGfxScrollFrame.cpp:639:3
    #27 0x7f871dde658a in nsHTMLScrollFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) /home/vladimir/proj/moz/mc-hg/layout/generic/nsGfxScrollFrame.cpp:874:3
    #28 0x7f871dcf97ff in nsBlockReflowContext::ReflowBlock(mozilla::LogicalRect const&, bool, nsCollapsingMargin&, int, bool, nsLineBox*, nsHTMLReflowState&, unsigned int&, nsBlockReflowState&) /home/vladimir/proj/moz/mc-hg/layout/generic/nsBlockReflowContext.cpp:306:3
    #29 0x7f871dceed76 in nsBlockFrame::ReflowBlockFrame(nsBlockReflowState&, nsLineList_iterator, bool*) /home/vladimir/proj/moz/mc-hg/layout/generic/nsBlockFrame.cpp:3350:7
    #30 0x7f871dcea737 in nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, bool*) /home/vladimir/proj/moz/mc-hg/layout/generic/nsBlockFrame.cpp:2711:5
....

==9378==ERROR: AddressSanitizer: memcpy-param-overlap: memory ranges [0x62d000a96406,0x62d000a96416) and [0x62d000a96402, 0x62d000a96412) overlap
    #0 0x4adb1c in __asan_memcpy (/home/vladimir/proj/moz/fx-asan-od/dist/bin/plugin-container+0x4adb1c)
--DOCSHELL 0x61a0002d0c80 == 9 [pid = 9293] [id = 10]
    #1 0x7f871fc9b246 in memmove16 /home/vladimir/proj/moz/mc-hg/modules/brotli/dec/decode.c:112:3
    #2 0x7f871fc9312a in BrotliDecompressStreaming /home/vladimir/proj/moz/mc-hg/modules/brotli/dec/decode.c:1557:11
    #3 0x7f871fc8d4d9 in BrotliDecompress /home/vladimir/proj/moz/mc-hg/modules/brotli/dec/decode.c:982:12
    #4 0x7f871fc8d03e in BrotliDecompressBuffer /home/vladimir/proj/moz/mc-hg/modules/brotli/dec/decode.c:973:26
    #5 0x7f871fc826d4 in ots::ConvertWOFF2ToSFNT(ots::Font*, unsigned char*, unsigned long, unsigned char const*, unsigned long) /home/vladimir/proj/moz/mc-hg/gfx/ots/src/woff2.cc:1022:8
    #6 0x7f871fc67491 in (anonymous namespace)::ProcessWOFF2(ots::OpenTypeFile*, ots::Font*, ots::OTSStream*, unsigned char const*, unsigned long) /home/vladimir/proj/moz/mc-hg/gfx/ots/src/ots.cc:480:8
    #7 0x7f871fc67491 in ots::OTSContext::Process(ots::OTSStream*, unsigned char const*, unsigned long, unsigned int) /home/vladimir/proj/moz/mc-hg/gfx/ots/src/ots.cc:888
    #8 0x7f8719a7a408 in gfxUserFontEntry::SanitizeOpenTypeData(unsigned char const*, unsigned int, unsigned int&, gfxUserFontType) /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxUserFontSet.cpp:243:9
    #9 0x7f8719a7dd3d in gfxUserFontEntry::LoadPlatformFont(unsigned char const*, unsigned int&) /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxUserFontSet.cpp:594:9
    #10 0x7f8719a7b7a8 in gfxUserFontEntry::LoadNextSrc() /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxUserFontSet.cpp:484:29
    #11 0x7f8719a74478 in gfxUserFontEntry::Load() /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxUserFontSet.cpp:676:9
    #12 0x7f8719a74478 in gfxFontGroup::GetFirstValidFont(unsigned int) /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxTextRun.cpp:1863
    #13 0x7f8719a74d6e in gfxFontGroup::MakeHyphenTextRun(gfxContext*, unsigned int) /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxTextRun.cpp:2005:21
    #14 0x7f8719a75104 in gfxFontGroup::GetHyphenWidth(gfxTextRun::PropertyProvider*) /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxTextRun.cpp:2023:25
    #15 0x7f871df0eabb in PropertyProvider::GetHyphenWidth() /home/vladimir/proj/moz/mc-hg/layout/generic/nsTextFrame.cpp:3370:20
    #16 0x7f871df372df in nsTextFrame::ReflowText(nsLineLayout&, int, nsRenderingContext*, nsHTMLReflowMetrics&, unsigned int&) /home/vladimir/proj/moz/mc-hg/layout/generic/nsTextFrame.cpp:8772:37
    #17 0x7f871dc8e988 in nsLineLayout::ReflowFrame(nsIFrame*, unsigned int&, nsHTMLReflowMetrics*, bool&) /home/vladimir/proj/moz/mc-hg/layout/generic/nsLineLayout.cpp:945:31
    #18 0x7f871dcff3a3 in nsBlockFrame::ReflowInlineFrame(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, nsIFrame*, LineReflowStatus*) /home/vladimir/proj/moz/mc-hg/layout/generic/nsBlockFrame.cpp:4037:3
    #19 0x7f871dcfd9e3 in nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState&, nsLineLayout&, nsLineList_iterator, nsFlowAreaRect&, int&, nsFloatManager::SavedState*, bool*, LineReflowStatus*, bool) /home/vladimir/proj/moz/mc-hg/layout/generic/nsBlockFrame.cpp:3839:5
    #20 0x7f871dcf264a in nsBlockFrame::ReflowInlineFrames(nsBlockReflowState&, nsLineList_iterator, bool*) /home/vladimir/proj/moz/mc-hg/layout/generic/nsBlockFrame.cpp:3705:9
    #21 0x7f871dcea778 in nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, bool*) /home/vladimir/proj/moz/mc-hg/layout/generic/nsBlockFrame.cpp:2714:5
    #22 0x7f871dcdf4ce in nsBlockFrame::ReflowDirtyLines(nsBlockReflowState&) /home/vladimir/proj/moz/mc-hg/layout/generic/nsBlockFrame.cpp:2249:7
    #23 0x7f871dcd75e6 in nsBlockFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) /home/vladimir/proj/moz/mc-hg/layout/generic/nsBlockFrame.cpp:1160:3
    #24 0x7f871dd4f818 in nsContainerFrame::ReflowChild(nsIFrame*, nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, mozilla::WritingMode const&, mozilla::LogicalPoint const&, nsSize const&, unsigned int, unsigned int&, nsOverflowContinuationTracker*) /home/vladimir/proj/moz/mc-hg/layout/generic/nsContainerFrame.cpp:996:3
    #25 0x7f871dde27d8 in nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState*, bool, bool, nsHTMLReflowMetrics*, bool) /home/vladimir/proj/moz/mc-hg/layout/generic/nsGfxScrollFrame.cpp:527:3
    #26 0x7f871dde43ef in nsHTMLScrollFrame::ReflowContents(ScrollReflowState*, nsHTMLReflowMetrics const&) /home/vladimir/proj/moz/mc-hg/layout/generic/nsGfxScrollFrame.cpp:639:3
    #27 0x7f871dde658a in nsHTMLScrollFrame::Reflow(nsPresContext*, nsHTMLReflowMetrics&, nsHTMLReflowState const&, unsigned int&) /home/vladimir/proj/moz/mc-hg/layout/generic/nsGfxScrollFrame.cpp:874:3
    #28 0x7f871dcf97ff in nsBlockReflowContext::ReflowBlock(mozilla::LogicalRect const&, bool, nsCollapsingMargin&, int, bool, nsLineBox*, nsHTMLReflowState&, unsigned int&, nsBlockReflowState&) /home/vladimir/proj/moz/mc-hg/layout/generic/nsBlockReflowContext.cpp:306:3
    #29 0x7f871dceed76 in nsBlockFrame::ReflowBlockFrame(nsBlockReflowState&, nsLineList_iterator, bool*) /home/vladimir/proj/moz/mc-hg/layout/generic/nsBlockFrame.cpp:3350:7
    #30 0x7f871dcea737 in nsBlockFrame::ReflowLine(nsBlockReflowState&, nsLineList_iterator, bool*) /home/vladimir/proj/moz/mc-hg/layout/generic/nsBlockFrame.cpp:2711:5
...

0x62d000a96402 is located 2 bytes inside of 33816-byte region [0x62d000a96400,0x62d000a9e818)
allocated by thread T0 (Web Content) here:
    #0 0x4c44f2 in __interceptor_malloc (/home/vladimir/proj/moz/fx-asan-od/dist/bin/plugin-container+0x4c44f2)
    #1 0x7f871fc8cc31 in BrotliAllocateRingBuffer /home/vladimir/proj/moz/mc-hg/modules/brotli/dec/decode.c:948:29
    #2 0x7f871fc8e259 in BrotliDecompressStreaming /home/vladimir/proj/moz/mc-hg/modules/brotli/dec/decode.c:1112:16
    #3 0x7f871fc8d4d9 in BrotliDecompress /home/vladimir/proj/moz/mc-hg/modules/brotli/dec/decode.c:982:12
    #4 0x7f871fc8d03e in BrotliDecompressBuffer /home/vladimir/proj/moz/mc-hg/modules/brotli/dec/decode.c:973:26
    #5 0x7f871fc826d4 in ots::ConvertWOFF2ToSFNT(ots::Font*, unsigned char*, unsigned long, unsigned char const*, unsigned long) /home/vladimir/proj/moz/mc-hg/gfx/ots/src/woff2.cc:1022:8
    #6 0x7f871fc67491 in (anonymous namespace)::ProcessWOFF2(ots::OpenTypeFile*, ots::Font*, ots::OTSStream*, unsigned char const*, unsigned long) /home/vladimir/proj/moz/mc-hg/gfx/ots/src/ots.cc:480:8
    #7 0x7f871fc67491 in ots::OTSContext::Process(ots::OTSStream*, unsigned char const*, unsigned long, unsigned int) /home/vladimir/proj/moz/mc-hg/gfx/ots/src/ots.cc:888
    #8 0x7f8719a7a408 in gfxUserFontEntry::SanitizeOpenTypeData(unsigned char const*, unsigned int, unsigned int&, gfxUserFontType) /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxUserFontSet.cpp:243:9
    #9 0x7f8719a7dd3d in gfxUserFontEntry::LoadPlatformFont(unsigned char const*, unsigned int&) /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxUserFontSet.cpp:594:9
    #10 0x7f8719a7b7a8 in gfxUserFontEntry::LoadNextSrc() /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxUserFontSet.cpp:484:29
    #11 0x7f8719a74478 in gfxUserFontEntry::Load() /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxUserFontSet.cpp:676:9
    #12 0x7f8719a74478 in gfxFontGroup::GetFirstValidFont(unsigned int) /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxTextRun.cpp:1863
    #13 0x7f8719a74d6e in gfxFontGroup::MakeHyphenTextRun(gfxContext*, unsigned int) /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxTextRun.cpp:2005:21
    #14 0x7f8719a75104 in gfxFontGroup::GetHyphenWidth(gfxTextRun::PropertyProvider*) /home/vladimir/proj/moz/mc-hg/gfx/thebes/gfxTextRun.cpp:2023:25
    #15 0x7f871df0eabb in PropertyProvider::GetHyphenWidth() /home/vladimir/proj/moz/mc-hg/layout/generic/nsTextFrame.cpp:3370:20
...
Reading these comments is the best thing you'll read all day:

http://mxr.mozilla.org/mozilla-central/source/modules/brotli/dec/decode.c#95

#if BROTLI_SAFE_MEMMOVE
  /* For x86 this compiles to the same binary as signle memcpy.
     On ARM memcpy is not inlined, so it works slower.
     This implementation makes decompression 1% slower than regular one,
     and 2% slower than NEON implementation.
   */
  uint32_t buffer[4];
  memcpy(buffer, src, 16);
  memcpy(dst, buffer, 16);
#elif defined(__ARM_NEON__)
  vst1q_u8(dst, vld1q_u8(src));
#else
  /* memcpy is unsafe for overlapping regions and ASAN detects this.
     But, because of optimizations, it works exactly as memmove:
     copies data to registers first, and then stores them to dst. */
  memcpy(dst, src, 16);
#endif
I.. guess we're missing a suppression? Or something?
>     But, because of optimizations, it works exactly as memmove:
>     copies data to registers first, and then stores them to dst. */

That seems like a risky assumption to make.  I don't see why this must be true
for all possible platform / toolchain variations until the end of time.

After all, memcpy(3) says:
The memory areas must not overlap.  Use memmove(3) if the memory areas do overlap.

I suggest we just s/memcpy/memmove/ here.
It looks like we could force the use of the "safe" version of this code by #define'ing BROTLI_BUILD_PORTABLE in our moz.build.
Upstreaming fixes would be good. This kind of thing should be fixed at the root.
This also affects a test in our tree, on Mac:
layout/reftests/font-face/woff2-1.html

We should just enable BROTLI_BUILD_PORTABLE (even in non-ASan, non-Valgrind builds) for now. Undefined behavior is not safe.

BROTLI_SAFE_MEMMOVE:
memmove16 should just call memmove. If any compilers routinely optimize memcpy(..16) into something overlap-safe, but turn memmove(..16) into something slower, bugs should be filed against them.

BROTLI_ALIGNED_READ:
There's a safe way to do an unaligned read, by expressing it as a small memcpy that gets optimized away.
Summary: ASAN memcpy-param-overlap on linux opening engadget.com → ASan memcpy-param-overlap in Brotli’s “memmove16” (e.g. opening engadget.com)
Attachment #8696067 - Flags: review?(jfkthame)
Assignee: nobody → mcmanus
Status: NEW → ASSIGNED
Before we just work around this in our build and move on, I think we should raise the issue with upstream as per comment 5. Has this been done?

At the least (IMO) the default should be a portable or "safe" build; if there are compiler-specific optimized-but-potentially-risky codepaths that are worth maintaining, they should be explicitly opt-in or based on detection of the specific toolchain.
I did point jyrki (upstream author) at this bug.. but I suspect the way it is written (to support either mode) is a design choice on their part because compile time switches don't write themselves :)
Blocks: 1243724
Comment on attachment 8696067 [details] [diff] [review]
define BUILD_PORTABLE for brotli

Review of attachment 8696067 [details] [diff] [review]:
-----------------------------------------------------------------

I guess we should go ahead and do this, given that bug 1243724 says there are platforms/environments where it becomes a real problem.
Attachment #8696067 - Flags: review?(jfkthame) → review+
I think the brotli default setting is quite dangerous. I reported it upstream. https://github.com/google/brotli/issues/307
The upstream response was quick: https://github.com/google/brotli/pull/308

Maybe use the patch(es) from there?
Duplicate of this bug: 1243724
1242904 contemplates taking the upstream code as a new patch to nightly.. I think we should ga with this change first and backport it.
Comment on attachment 8696067 [details] [diff] [review]
define BUILD_PORTABLE for brotli

Approval Request Comment
[Feature/regressing bug #]: woff2
[User impact if declined]: potential crashes, real crash on tier 3
[Describe test coverage new/current, TreeHerder]: asan identifies
[Risks and why]: potential speed reduction, but small enough I haven't been able to measure it
[String/UUID change made/needed]:none

enable a non default build option for the brotli library for increased memory safety.

the brotli library we include uses memcpy in a non standard way that they've verified is safe for our tier 1 platforms.. but we've seen a problem elsewhere and generally think its safer to enable this option.
Attachment #8696067 - Flags: approval-mozilla-beta?
Attachment #8696067 - Flags: approval-mozilla-aurora?
(In reply to Patrick McManus [:mcmanus] from comment #15)
> 1242904 contemplates taking the upstream code as a new patch to nightly.. I
> think we should ga with this change first and backport it.

FWIW, I was going to suggest the same thing -- I agree this is the smallest/safest option for uplift purposes.
https://hg.mozilla.org/mozilla-central/rev/0012027267e6
Status: ASSIGNED → RESOLVED
Closed: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla47
Comment on attachment 8696067 [details] [diff] [review]
define BUILD_PORTABLE for brotli

Avoid crashes, taking it.

Should be in 45 beta 2.
Attachment #8696067 - Flags: approval-mozilla-beta?
Attachment #8696067 - Flags: approval-mozilla-beta+
Attachment #8696067 - Flags: approval-mozilla-aurora?
Attachment #8696067 - Flags: approval-mozilla-aurora+
Btw, this is what DEFINES is for.
You need to log in before you can comment on or make changes to this bug.