diff --git a/gnu-system.am b/gnu-system.am index 2749a1bca7..c42843af93 100644 --- a/gnu-system.am +++ b/gnu-system.am @@ -379,6 +379,15 @@ dist_patch_DATA = \ gnu/packages/patches/guix-test-networking.patch \ gnu/packages/patches/gtkglext-disable-disable-deprecated.patch \ gnu/packages/patches/hop-bigloo-4.0b.patch \ + gnu/packages/patches/icecat-CVE-2014-1587-bug-1042567.patch \ + gnu/packages/patches/icecat-CVE-2014-1587-bug-1072847.patch \ + gnu/packages/patches/icecat-CVE-2014-1587-bug-1079729.patch \ + gnu/packages/patches/icecat-CVE-2014-1587-bug-1080312.patch \ + gnu/packages/patches/icecat-CVE-2014-1587-bug-1089207.patch \ + gnu/packages/patches/icecat-CVE-2014-1590.patch \ + gnu/packages/patches/icecat-CVE-2014-1592.patch \ + gnu/packages/patches/icecat-CVE-2014-1593.patch \ + gnu/packages/patches/icecat-CVE-2014-1594.patch \ gnu/packages/patches/inkscape-stray-comma.patch \ gnu/packages/patches/jbig2dec-ignore-testtest.patch \ gnu/packages/patches/kmod-module-directory.patch \ diff --git a/gnu/packages/gnuzilla.scm b/gnu/packages/gnuzilla.scm index 2781447685..2550bdf4f5 100644 --- a/gnu/packages/gnuzilla.scm +++ b/gnu/packages/gnuzilla.scm @@ -53,7 +53,17 @@ version "/" name "-" version ".tar.xz")) (sha256 (base32 - "02r9klfc0z26w270inq652249hq0wfzvwhzvwmk0n8v8nzkk5idh")))) + "02r9klfc0z26w270inq652249hq0wfzvwhzvwmk0n8v8nzkk5idh")) + (patches (map search-patch + '("icecat-CVE-2014-1587-bug-1042567.patch" + "icecat-CVE-2014-1587-bug-1072847.patch" + "icecat-CVE-2014-1587-bug-1079729.patch" + "icecat-CVE-2014-1587-bug-1080312.patch" + "icecat-CVE-2014-1587-bug-1089207.patch" + "icecat-CVE-2014-1590.patch" + "icecat-CVE-2014-1592.patch" + "icecat-CVE-2014-1593.patch" + "icecat-CVE-2014-1594.patch"))))) (build-system gnu-build-system) (inputs `(("alsa-lib" ,alsa-lib) diff --git a/gnu/packages/patches/icecat-CVE-2014-1587-bug-1042567.patch b/gnu/packages/patches/icecat-CVE-2014-1587-bug-1042567.patch new file mode 100644 index 0000000000..4e45e3062f --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2014-1587-bug-1042567.patch @@ -0,0 +1,30 @@ +commit 60529fc02cf10482d8fecd699eea271ddc22bcb9 +Author: Jason Orendorff +Date: Thu Aug 28 15:43:57 2014 -0500 + + Bug 1042567 - Reflect JSPropertyOp properties more consistently as data properties. r=efaust, a=lmandel + + Modified js/src/jsobj.cpp +diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp +index 2745509..ad336f3 100644 +--- a/js/src/jsobj.cpp ++++ b/js/src/jsobj.cpp +@@ -235,11 +235,18 @@ js::GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id, + if (pobj->isNative()) { + desc.setAttributes(GetShapeAttributes(pobj, shape)); + if (desc.hasGetterOrSetterObject()) { ++ MOZ_ASSERT(desc.isShared()); + doGet = false; + if (desc.hasGetterObject()) + desc.setGetterObject(shape->getterObject()); + if (desc.hasSetterObject()) + desc.setSetterObject(shape->setterObject()); ++ } else { ++ // This is either a straight-up data property or (rarely) a ++ // property with a JSPropertyOp getter/setter. The latter must be ++ // reported to the caller as a plain data property, so don't ++ // populate desc.getter/setter, and mask away the SHARED bit. ++ desc.attributesRef() &= ~JSPROP_SHARED; + } + } else { + if (!JSObject::getGenericAttributes(cx, pobj, id, &desc.attributesRef())) diff --git a/gnu/packages/patches/icecat-CVE-2014-1587-bug-1072847.patch b/gnu/packages/patches/icecat-CVE-2014-1587-bug-1072847.patch new file mode 100644 index 0000000000..448b096b81 --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2014-1587-bug-1072847.patch @@ -0,0 +1,19 @@ +commit 5d91f3b10f999e852e0392470198bd6aefc87e1e +Author: Jeff Muizelaar +Date: Tue Oct 28 10:08:25 2014 -0400 + + Bug 1072847 - Initialize mSurface. r=BenWa, a=bkerensa + + Modified gfx/2d/DrawTargetCairo.cpp +diff --git a/gfx/2d/DrawTargetCairo.cpp b/gfx/2d/DrawTargetCairo.cpp +index 48c2c73..78d9e4f 100644 +--- a/gfx/2d/DrawTargetCairo.cpp ++++ b/gfx/2d/DrawTargetCairo.cpp +@@ -353,6 +353,7 @@ NeedIntermediateSurface(const Pattern& aPattern, const DrawOptions& aOptions) + + DrawTargetCairo::DrawTargetCairo() + : mContext(nullptr) ++ , mSurface(nullptr) + , mLockedBits(nullptr) + { + } diff --git a/gnu/packages/patches/icecat-CVE-2014-1587-bug-1079729.patch b/gnu/packages/patches/icecat-CVE-2014-1587-bug-1079729.patch new file mode 100644 index 0000000000..3ef60baaad --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2014-1587-bug-1079729.patch @@ -0,0 +1,191 @@ +commit 5de6730cc26744b9efcf4d4adb4a4c45023ef8a0 +Author: Randell Jesup +Date: Tue Oct 28 11:06:00 2014 -0400 + + Bug 1079729: Fix handling of increasing number of SCTP channels used by DataChannels r=tuexen a=lsblakk + + Modified media/webrtc/signaling/src/sipcc/core/gsm/h/fsm.h +diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/h/fsm.h b/media/webrtc/signaling/src/sipcc/core/gsm/h/fsm.h +index ba8e1ff..8d964f1 100755 +--- a/media/webrtc/signaling/src/sipcc/core/gsm/h/fsm.h ++++ b/media/webrtc/signaling/src/sipcc/core/gsm/h/fsm.h +@@ -225,7 +225,7 @@ typedef struct fsmdef_media_t_ { + /* + * Data Channel properties + */ +-#define WEBRTC_DATACHANNEL_STREAMS_DEFAULT 16 ++#define WEBRTC_DATACHANNEL_STREAMS_DEFAULT 256 + uint32 datachannel_streams; + char datachannel_protocol[SDP_MAX_STRING_LEN + 1]; + + Modified netwerk/sctp/datachannel/DataChannel.cpp +diff --git a/netwerk/sctp/datachannel/DataChannel.cpp b/netwerk/sctp/datachannel/DataChannel.cpp +index 414e3db..a00d938 100644 +--- a/netwerk/sctp/datachannel/DataChannel.cpp ++++ b/netwerk/sctp/datachannel/DataChannel.cpp +@@ -910,10 +910,12 @@ DataChannelConnection::RequestMoreStreams(int32_t aNeeded) + uint32_t outStreamsNeeded; + socklen_t len; + +- if (aNeeded + mStreams.Length() > MAX_NUM_STREAMS) ++ if (aNeeded + mStreams.Length() > MAX_NUM_STREAMS) { + aNeeded = MAX_NUM_STREAMS - mStreams.Length(); +- if (aNeeded <= 0) ++ } ++ if (aNeeded <= 0) { + return false; ++ } + + len = (socklen_t)sizeof(struct sctp_status); + if (usrsctp_getsockopt(mMasterSocket, IPPROTO_SCTP, SCTP_STATUS, &status, &len) < 0) { +@@ -922,19 +924,25 @@ DataChannelConnection::RequestMoreStreams(int32_t aNeeded) + } + outStreamsNeeded = aNeeded; // number to add + +- memset(&sas, 0, sizeof(struct sctp_add_streams)); ++ // Note: if multiple channel opens happen when we don't have enough space, ++ // we'll call RequestMoreStreams() multiple times ++ memset(&sas, 0, sizeof(sas)); + sas.sas_instrms = 0; + sas.sas_outstrms = (uint16_t)outStreamsNeeded; /* XXX error handling */ + // Doesn't block, we get an event when it succeeds or fails + if (usrsctp_setsockopt(mMasterSocket, IPPROTO_SCTP, SCTP_ADD_STREAMS, &sas, + (socklen_t) sizeof(struct sctp_add_streams)) < 0) { +- if (errno == EALREADY) ++ if (errno == EALREADY) { ++ LOG(("Already have %u output streams", outStreamsNeeded)); + return true; ++ } + + LOG(("***failed: setsockopt ADD errno=%d", errno)); + return false; + } + LOG(("Requested %u more streams", outStreamsNeeded)); ++ // We add to mStreams when we get a SCTP_STREAM_CHANGE_EVENT and the ++ // values are larger than mStreams.Length() + return true; + } + +@@ -1050,6 +1058,13 @@ DataChannelConnection::SendDeferredMessages() + channel->mFlags & DATA_CHANNEL_FLAGS_OUT_OF_ORDER_ALLOWED, + channel->mPrPolicy, channel->mPrValue)) { + channel->mFlags &= ~DATA_CHANNEL_FLAGS_SEND_REQ; ++ ++ channel->mState = OPEN; ++ channel->mReady = true; ++ LOG(("%s: sending ON_CHANNEL_OPEN for %p", __FUNCTION__, channel.get())); ++ NS_DispatchToMainThread(new DataChannelOnMessageAvailable( ++ DataChannelOnMessageAvailable::ON_CHANNEL_OPEN, this, ++ channel)); + sent = true; + } else { + if (errno == EAGAIN || errno == EWOULDBLOCK) { +@@ -1177,6 +1192,7 @@ DataChannelConnection::HandleOpenRequestMessage(const struct rtcweb_datachannel_ + prPolicy = SCTP_PR_SCTP_TTL; + break; + default: ++ LOG(("Unknown channel type", req->channel_type)); + /* XXX error handling */ + return; + } +@@ -1203,6 +1219,10 @@ DataChannelConnection::HandleOpenRequestMessage(const struct rtcweb_datachannel_ + } + return; + } ++ if (stream >= mStreams.Length()) { ++ LOG(("%s: stream %u out of bounds (%u)", __FUNCTION__, stream, mStreams.Length())); ++ return; ++ } + + nsCString label(nsDependentCSubstring(&req->label[0], ntohs(req->label_length))); + nsCString protocol(nsDependentCSubstring(&req->label[ntohs(req->label_length)], +@@ -1220,8 +1240,8 @@ DataChannelConnection::HandleOpenRequestMessage(const struct rtcweb_datachannel_ + + channel->mState = DataChannel::WAITING_TO_OPEN; + +- LOG(("%s: sending ON_CHANNEL_CREATED for %s/%s: %u", __FUNCTION__, +- channel->mLabel.get(), channel->mProtocol.get(), stream)); ++ LOG(("%s: sending ON_CHANNEL_CREATED for %s/%s: %u (state %u)", __FUNCTION__, ++ channel->mLabel.get(), channel->mProtocol.get(), stream, channel->mState)); + NS_DispatchToMainThread(new DataChannelOnMessageAvailable( + DataChannelOnMessageAvailable::ON_CHANNEL_CREATED, + this, channel)); +@@ -1739,13 +1759,14 @@ DataChannelConnection::HandleStreamResetEvent(const struct sctp_stream_reset_eve + // 2. We sent our own reset (CLOSING); either they crossed on the + // wire, or this is a response to our Reset. + // Go to CLOSED +- // 3. We've sent a open but haven't gotten a response yet (OPENING) ++ // 3. We've sent a open but haven't gotten a response yet (CONNECTING) + // I believe this is impossible, as we don't have an input stream yet. + + LOG(("Incoming: Channel %u closed, state %d", + channel->mStream, channel->mState)); + ASSERT_WEBRTC(channel->mState == DataChannel::OPEN || + channel->mState == DataChannel::CLOSING || ++ channel->mState == DataChannel::CONNECTING || + channel->mState == DataChannel::WAITING_TO_OPEN); + if (channel->mState == DataChannel::OPEN || + channel->mState == DataChannel::WAITING_TO_OPEN) { +@@ -1791,20 +1812,21 @@ DataChannelConnection::HandleStreamChangeEvent(const struct sctp_stream_change_e + return; + } else { + if (strchg->strchange_instrms > mStreams.Length()) { +- LOG(("Other side increased streamds from %u to %u", ++ LOG(("Other side increased streams from %u to %u", + mStreams.Length(), strchg->strchange_instrms)); + } +- if (strchg->strchange_outstrms > mStreams.Length()) { ++ if (strchg->strchange_outstrms > mStreams.Length() || ++ strchg->strchange_instrms > mStreams.Length()) { + uint16_t old_len = mStreams.Length(); ++ uint16_t new_len = std::max(strchg->strchange_outstrms, ++ strchg->strchange_instrms); + LOG(("Increasing number of streams from %u to %u - adding %u (in: %u)", +- old_len, +- strchg->strchange_outstrms, +- strchg->strchange_outstrms - old_len, ++ old_len, new_len, new_len - old_len, + strchg->strchange_instrms)); + // make sure both are the same length +- mStreams.AppendElements(strchg->strchange_outstrms - old_len); ++ mStreams.AppendElements(new_len - old_len); + LOG(("New length = %d (was %d)", mStreams.Length(), old_len)); +- for (uint32_t i = old_len; i < mStreams.Length(); ++i) { ++ for (size_t i = old_len; i < mStreams.Length(); ++i) { + mStreams[i] = nullptr; + } + // Re-process any channels waiting for streams. +@@ -1815,13 +1837,17 @@ DataChannelConnection::HandleStreamChangeEvent(const struct sctp_stream_change_e + // Could make a more complex API for OpenXxxFinish() and avoid this loop + int32_t num_needed = mPending.GetSize(); + LOG(("%d of %d new streams already needed", num_needed, +- strchg->strchange_outstrms - old_len)); +- num_needed -= (strchg->strchange_outstrms - old_len); // number we added ++ new_len - old_len)); ++ num_needed -= (new_len - old_len); // number we added + if (num_needed > 0) { + if (num_needed < 16) + num_needed = 16; + LOG(("Not enough new streams, asking for %d more", num_needed)); + RequestMoreStreams(num_needed); ++ } else if (strchg->strchange_outstrms < strchg->strchange_instrms) { ++ LOG(("Requesting %d output streams to match partner", ++ strchg->strchange_instrms - strchg->strchange_outstrms)); ++ RequestMoreStreams(strchg->strchange_instrms - strchg->strchange_outstrms); + } + + ProcessQueuedOpens(); + Modified netwerk/sctp/datachannel/DataChannelProtocol.h +diff --git a/netwerk/sctp/datachannel/DataChannelProtocol.h b/netwerk/sctp/datachannel/DataChannelProtocol.h +index 549f74b..74fbe58 100644 +--- a/netwerk/sctp/datachannel/DataChannelProtocol.h ++++ b/netwerk/sctp/datachannel/DataChannelProtocol.h +@@ -17,7 +17,7 @@ + #endif + + // Duplicated in fsm.def +-#define WEBRTC_DATACHANNEL_STREAMS_DEFAULT 16 ++#define WEBRTC_DATACHANNEL_STREAMS_DEFAULT 256 + + #define DATA_CHANNEL_PPID_CONTROL 50 + #define DATA_CHANNEL_PPID_BINARY 52 diff --git a/gnu/packages/patches/icecat-CVE-2014-1587-bug-1080312.patch b/gnu/packages/patches/icecat-CVE-2014-1587-bug-1080312.patch new file mode 100644 index 0000000000..5efac49e12 --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2014-1587-bug-1080312.patch @@ -0,0 +1,308 @@ +commit d74bdb4589ad714e2a45e282974db075de2be673 +Author: Randell Jesup +Date: Wed Nov 12 22:59:53 2014 -0500 + + Bug 1080312 - Update iteration code from upstream. r=jesup, a=abillings + + Modified netwerk/sctp/src/moz.build +diff --git a/netwerk/sctp/src/moz.build b/netwerk/sctp/src/moz.build +index 1901a41..82103b9 100644 +--- a/netwerk/sctp/src/moz.build ++++ b/netwerk/sctp/src/moz.build +@@ -31,7 +31,6 @@ SOURCES += [ + 'user_environment.c', + 'user_mbuf.c', + 'user_recv_thread.c', +- 'user_sctp_timer_iterate.c', + 'user_socket.c', + ] + + Modified netwerk/sctp/src/netinet/sctp_callout.c +diff --git a/netwerk/sctp/src/netinet/sctp_callout.c b/netwerk/sctp/src/netinet/sctp_callout.c +index 67b7566..e8ac77f 100755 +--- a/netwerk/sctp/src/netinet/sctp_callout.c ++++ b/netwerk/sctp/src/netinet/sctp_callout.c +@@ -30,9 +30,27 @@ + * THE POSSIBILITY OF SUCH DAMAGE. + */ + ++#if defined(__Userspace__) ++#include ++#if !defined (__Userspace_os_Windows) ++#include ++#include ++#include ++#endif ++#if defined(__Userspace_os_NaCl) ++#include ++#endif ++#include ++#include ++#include ++#include ++#include ++#include ++#else + #include + #include + #include ++#endif + + /* + * Callout/Timer routines for OS that doesn't have them +@@ -117,24 +135,16 @@ sctp_os_timer_stop(sctp_os_timer_t *c) + return (1); + } + +-#if defined(__APPLE__) +-/* +- * For __APPLE__, use a single main timer at a faster resolution than +- * fastim. The timer just calls this existing callout infrastructure. +- */ +-#endif +-void +-sctp_timeout(void *arg SCTP_UNUSED) ++static void ++sctp_handle_tick(int delta) + { + sctp_os_timer_t *c; + void (*c_func)(void *); + void *c_arg; + + SCTP_TIMERQ_LOCK(); +-#if defined(__APPLE__) + /* update our tick count */ +- ticks += SCTP_BASE_VAR(sctp_main_timer_ticks); +-#endif ++ ticks += delta; + c = TAILQ_FIRST(&SCTP_BASE_INFO(callqueue)); + while (c) { + if (c->c_time <= ticks) { +@@ -155,9 +165,60 @@ sctp_timeout(void *arg SCTP_UNUSED) + } + sctp_os_timer_next = NULL; + SCTP_TIMERQ_UNLOCK(); ++} + + #if defined(__APPLE__) +- /* restart the main timer */ ++void ++sctp_timeout(void *arg SCTP_UNUSED) ++{ ++ sctp_handle_tick(SCTP_BASE_VAR(sctp_main_timer_ticks)); + sctp_start_main_timer(); ++} + #endif ++ ++#if defined(__Userspace__) ++#define TIMEOUT_INTERVAL 10 ++ ++void * ++user_sctp_timer_iterate(void *arg) ++{ ++ for (;;) { ++#if defined (__Userspace_os_Windows) ++ Sleep(TIMEOUT_INTERVAL); ++#else ++ struct timeval timeout; ++ ++ timeout.tv_sec = 0; ++ timeout.tv_usec = 1000 * TIMEOUT_INTERVAL; ++ select(0, NULL, NULL, NULL, &timeout); ++#endif ++ if (SCTP_BASE_VAR(timer_thread_should_exit)) { ++ break; ++ } ++ sctp_handle_tick(MSEC_TO_TICKS(TIMEOUT_INTERVAL)); ++ } ++ return (NULL); + } ++ ++void ++sctp_start_timer(void) ++{ ++ /* ++ * No need to do SCTP_TIMERQ_LOCK_INIT(); ++ * here, it is being done in sctp_pcb_init() ++ */ ++#if defined (__Userspace_os_Windows) ++ if ((SCTP_BASE_VAR(timer_thread) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)user_sctp_timer_iterate, NULL, 0, NULL)) == NULL) { ++ SCTP_PRINTF("ERROR; Creating ithread failed\n"); ++ } ++#else ++ int rc; ++ ++ rc = pthread_create(&SCTP_BASE_VAR(timer_thread), NULL, user_sctp_timer_iterate, NULL); ++ if (rc) { ++ SCTP_PRINTF("ERROR; return code from pthread_create() is %d\n", rc); ++ } ++#endif ++} ++ ++#endif + Modified netwerk/sctp/src/netinet/sctp_callout.h +diff --git a/netwerk/sctp/src/netinet/sctp_callout.h b/netwerk/sctp/src/netinet/sctp_callout.h +index 2782945..c53c5a4 100755 +--- a/netwerk/sctp/src/netinet/sctp_callout.h ++++ b/netwerk/sctp/src/netinet/sctp_callout.h +@@ -64,7 +64,6 @@ __FBSDID("$FreeBSD$"); + #endif + + extern int ticks; +-extern void sctp_start_timer(); + #endif + + TAILQ_HEAD(calloutlist, sctp_callout); +@@ -94,6 +93,11 @@ int sctp_os_timer_stop(sctp_os_timer_t *); + #define SCTP_OS_TIMER_ACTIVE(tmr) ((tmr)->c_flags & SCTP_CALLOUT_ACTIVE) + #define SCTP_OS_TIMER_DEACTIVATE(tmr) ((tmr)->c_flags &= ~SCTP_CALLOUT_ACTIVE) + ++#if defined(__Userspace__) ++void sctp_start_timer(void); ++#endif ++#if defined(__APPLE__) + void sctp_timeout(void *); ++#endif + + #endif + Modified netwerk/sctp/src/netinet/sctp_usrreq.c +diff --git a/netwerk/sctp/src/netinet/sctp_usrreq.c b/netwerk/sctp/src/netinet/sctp_usrreq.c +index d4115ad..c17ea04 100755 +--- a/netwerk/sctp/src/netinet/sctp_usrreq.c ++++ b/netwerk/sctp/src/netinet/sctp_usrreq.c +@@ -56,6 +56,9 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 259943 2013-12-27 13:07:00Z t + #include + #include + #include ++#if defined(__Userspace__) ++#include ++#endif + #if !defined(__Userspace_os_Windows) + #include + #endif + Deleted netwerk/sctp/src/user_sctp_timer_iterate.c +diff --git a/netwerk/sctp/src/user_sctp_timer_iterate.c b/netwerk/sctp/src/user_sctp_timer_iterate.c +deleted file mode 100755 +index 0a9dbce..0000000 +--- a/netwerk/sctp/src/user_sctp_timer_iterate.c ++++ /dev/null +@@ -1,119 +0,0 @@ +-/*- +- * Copyright (c) 2012 Michael Tuexen +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- * +- */ +- +-#include +-#if !defined (__Userspace_os_Windows) +-#include +-#include +-#include +-#endif +-#include +-#include +-#include +-#include +-#include +-#include +-#include "netinet/sctp_callout.h" +- +-/* This is the polling time of callqueue in milliseconds +- * 10ms seems to work well. 1ms was giving erratic behavior +- */ +-#define TIMEOUT_INTERVAL 10 +- +-extern int ticks; +- +-void * +-user_sctp_timer_iterate(void *arg) +-{ +- sctp_os_timer_t *c; +- void (*c_func)(void *); +- void *c_arg; +- sctp_os_timer_t *sctp_os_timer_next; +- /* +- * The MSEC_TO_TICKS conversion depends on hz. The to_ticks in +- * sctp_os_timer_start also depends on hz. E.g. if hz=1000 then +- * for multiple INIT the to_ticks is 2000, 4000, 8000, 16000, 32000, 60000 +- * and further to_ticks level off at 60000 i.e. 60 seconds. +- * If hz=100 then for multiple INIT the to_ticks are 200, 400, 800 and so-on. +- */ +- for (;;) { +-#if defined (__Userspace_os_Windows) +- Sleep(TIMEOUT_INTERVAL); +-#else +- struct timeval timeout; +- +- timeout.tv_sec = 0; +- timeout.tv_usec = 1000 * TIMEOUT_INTERVAL; +- select(0, NULL, NULL, NULL, &timeout); +-#endif +- if (SCTP_BASE_VAR(timer_thread_should_exit)) { +- break; +- } +- SCTP_TIMERQ_LOCK(); +- /* update our tick count */ +- ticks += MSEC_TO_TICKS(TIMEOUT_INTERVAL); +- c = TAILQ_FIRST(&SCTP_BASE_INFO(callqueue)); +- while (c) { +- if (c->c_time <= ticks) { +- sctp_os_timer_next = TAILQ_NEXT(c, tqe); +- TAILQ_REMOVE(&SCTP_BASE_INFO(callqueue), c, tqe); +- c_func = c->c_func; +- c_arg = c->c_arg; +- c->c_flags &= ~SCTP_CALLOUT_PENDING; +- SCTP_TIMERQ_UNLOCK(); +- c_func(c_arg); +- SCTP_TIMERQ_LOCK(); +- c = sctp_os_timer_next; +- } else { +- c = TAILQ_NEXT(c, tqe); +- } +- } +- SCTP_TIMERQ_UNLOCK(); +- } +- return (NULL); +-} +- +-void +-sctp_start_timer(void) +-{ +- /* +- * No need to do SCTP_TIMERQ_LOCK_INIT(); +- * here, it is being done in sctp_pcb_init() +- */ +-#if defined (__Userspace_os_Windows) +- if ((SCTP_BASE_VAR(timer_thread) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)user_sctp_timer_iterate, NULL, 0, NULL)) == NULL) { +- SCTP_PRINTF("ERROR; Creating ithread failed\n"); +- } +-#else +- int rc; +- +- rc = pthread_create(&SCTP_BASE_VAR(timer_thread), NULL, user_sctp_timer_iterate, NULL); +- if (rc) { +- SCTP_PRINTF("ERROR; return code from pthread_create() is %d\n", rc); +- } +-#endif +-} diff --git a/gnu/packages/patches/icecat-CVE-2014-1587-bug-1089207.patch b/gnu/packages/patches/icecat-CVE-2014-1587-bug-1089207.patch new file mode 100644 index 0000000000..cd5602c86b --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2014-1587-bug-1089207.patch @@ -0,0 +1,119 @@ +commit 9df10fea93b483af6646ef2f7aab35598fbaab2f +Author: Nils Ohlmeier [:drno] +Date: Thu Nov 6 12:21:57 2014 -0500 + + Bug 1089207: fix parsing of invalid fmtp att r=drno,jesup a=lmandel + + Modified media/webrtc/signaling/src/sipcc/core/sdp/sdp_attr.c +diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_attr.c b/media/webrtc/signaling/src/sipcc/core/sdp/sdp_attr.c +index fa5ca2e..33d26c0 100644 +--- a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_attr.c ++++ b/media/webrtc/signaling/src/sipcc/core/sdp/sdp_attr.c +@@ -458,7 +458,6 @@ sdp_result_e sdp_parse_attr_fmtp (sdp_t *sdp_p, sdp_attr_t *attr_p, + char tmp[SDP_MAX_STRING_LEN]; + char *src_ptr; + char *temp_ptr = NULL; +- tinybool flag=FALSE; + char *tok=NULL; + char *temp=NULL; + u16 custom_x=0; +@@ -495,29 +494,11 @@ sdp_result_e sdp_parse_attr_fmtp (sdp_t *sdp_p, sdp_attr_t *attr_p, + fmtp_p->packetization_mode = 0; + fmtp_p->level_asymmetry_allowed = SDP_DEFAULT_LEVEL_ASYMMETRY_ALLOWED_VALUE; + +- /* BEGIN - a typical macro fn to replace '/' with ';' from fmtp line*/ +- /* This ugly replacement of '/' with ';' is only done because +- * econf/MS client sends in this wierd /illegal format. +- * fmtp parameters MUST be separated by ';' +- */ + temp_ptr = cpr_strdup(ptr); + if (temp_ptr == NULL) { + return (SDP_FAILURE); + } + fmtp_ptr = src_ptr = temp_ptr; +- while (flag == FALSE) { +- if (*src_ptr == '\n') { +- flag = TRUE; +- break; +- } +- if (*src_ptr == '/') { +- *src_ptr =';' ; +- } +- src_ptr++; +- } +- /* END */ +- /* Once we move to RFC compliant video codec implementations, the above +- * patch should be removed */ + + src_ptr = temp_ptr; + while (!done) { + Modified media/webrtc/signaling/src/sipcc/core/sdp/sdp_main.c +diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_main.c b/media/webrtc/signaling/src/sipcc/core/sdp/sdp_main.c +index 0be02aa..9760d4e 100644 +--- a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_main.c ++++ b/media/webrtc/signaling/src/sipcc/core/sdp/sdp_main.c +@@ -1002,7 +1002,12 @@ sdp_result_e sdp_parse (sdp_t *sdp_p, char **bufp, u16 len) + */ + ptr = next_ptr; + line_end = sdp_findchar(ptr, "\n"); +- if (line_end >= (*bufp + len)) { ++ if ((line_end >= (*bufp + len)) || ++ (*line_end == '\0')) { ++ /* As this does not update the result value the SDP up to this point ++ * is still accept as valid. So encountering this is not treated as ++ * an error. ++ */ + sdp_parse_error(sdp_p->peerconnection, + "%s End of line beyond end of buffer.", + sdp_p->debug_str); + Modified media/webrtc/signaling/test/sdp_unittests.cpp +diff --git a/media/webrtc/signaling/test/sdp_unittests.cpp b/media/webrtc/signaling/test/sdp_unittests.cpp +index 51df09b..9f98eed 100644 +--- a/media/webrtc/signaling/test/sdp_unittests.cpp ++++ b/media/webrtc/signaling/test/sdp_unittests.cpp +@@ -755,13 +755,13 @@ TEST_F(SdpTest, parseFmtpMaxFs) { + u32 val = 0; + ParseSdp(kVideoSdp + "a=fmtp:120 max-fs=300;max-fr=30\r\n"); + ASSERT_EQ(sdp_attr_get_fmtp_max_fs(sdp_ptr_, 1, 0, 1, &val), SDP_SUCCESS); +- ASSERT_EQ(val, 300); ++ ASSERT_EQ(val, 300U); + } + TEST_F(SdpTest, parseFmtpMaxFr) { + u32 val = 0; + ParseSdp(kVideoSdp + "a=fmtp:120 max-fs=300;max-fr=30\r\n"); + ASSERT_EQ(sdp_attr_get_fmtp_max_fr(sdp_ptr_, 1, 0, 1, &val), SDP_SUCCESS); +- ASSERT_EQ(val, 30); ++ ASSERT_EQ(val, 30U); + } + + TEST_F(SdpTest, addFmtpMaxFs) { +@@ -789,6 +789,29 @@ TEST_F(SdpTest, addFmtpMaxFsFr) { + std::string::npos); + } + ++static const std::string kBrokenFmtp = ++ "v=0\r\n" ++ "o=- 137331303 2 IN IP4 127.0.0.1\r\n" ++ "s=SIP Call\r\n" ++ "t=0 0\r\n" ++ "m=video 56436 RTP/SAVPF 120\r\n" ++ "c=IN IP4 198.51.100.7\r\n" ++ "a=rtpmap:120 VP8/90000\r\n" ++ /* Note: the \0 in this string triggered bz://1089207 ++ */ ++ "a=fmtp:120 max-fs=300;max\0fr=30"; ++ ++TEST_F(SdpTest, parseBrokenFmtp) { ++ u32 val = 0; ++ char *buf = const_cast(kBrokenFmtp.data()); ++ ResetSdp(); ++ /* We need to manually invoke the parser here to be able to specify the length ++ * of the string beyond the \0 in last line of the string. ++ */ ++ ASSERT_EQ(sdp_parse(sdp_ptr_, &buf, 165), SDP_SUCCESS); ++ ASSERT_EQ(sdp_attr_get_fmtp_max_fs(sdp_ptr_, 1, 0, 1, &val), SDP_INVALID_PARAMETER); ++} ++ + } // End namespace test. + + int main(int argc, char **argv) { diff --git a/gnu/packages/patches/icecat-CVE-2014-1590.patch b/gnu/packages/patches/icecat-CVE-2014-1590.patch new file mode 100644 index 0000000000..f8513980ad --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2014-1590.patch @@ -0,0 +1,33 @@ +commit 50c5ca4bacf7cda77c3a7ab1b8d82ded18fb3355 +Author: Olli Pettay +Date: Sun Nov 2 22:01:55 2014 +0200 + + Bug 1087633 - Filter out XPConnect wrapped input streams. r=bz, a=lmandel + + Modified content/base/src/nsXMLHttpRequest.h +diff --git a/content/base/src/nsXMLHttpRequest.h b/content/base/src/nsXMLHttpRequest.h +index b1fc4e3..4ab4f29 100644 +--- a/content/base/src/nsXMLHttpRequest.h ++++ b/content/base/src/nsXMLHttpRequest.h +@@ -28,7 +28,8 @@ + #include "nsIPrincipal.h" + #include "nsIScriptObjectPrincipal.h" + #include "nsISizeOfEventTarget.h" +- ++#include "nsIXPConnect.h" ++#include "nsIInputStream.h" + #include "mozilla/Assertions.h" + #include "mozilla/DOMEventTargetHelper.h" + #include "mozilla/MemoryReporting.h" +@@ -446,6 +447,11 @@ public: + void Send(nsIInputStream* aStream, ErrorResult& aRv) + { + NS_ASSERTION(aStream, "Null should go to string version"); ++ nsCOMPtr wjs = do_QueryInterface(aStream); ++ if (wjs) { ++ aRv.Throw(NS_ERROR_DOM_TYPE_ERR); ++ return; ++ } + aRv = Send(RequestBody(aStream)); + } + void SendAsBinary(const nsAString& aBody, ErrorResult& aRv); diff --git a/gnu/packages/patches/icecat-CVE-2014-1592.patch b/gnu/packages/patches/icecat-CVE-2014-1592.patch new file mode 100644 index 0000000000..6de1b6fe4a --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2014-1592.patch @@ -0,0 +1,400 @@ +commit 7efadbb03cdffa11ebfc2da3113377d2f33b893b +Author: Henri Sivonen +Date: Mon Nov 3 15:23:26 2014 +0200 + + Bug 1088635. r=smaug, a=bkerensa + + Modified content/base/src/nsDocument.cpp +diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp +index cbed38d..3493bce 100644 +--- a/content/base/src/nsDocument.cpp ++++ b/content/base/src/nsDocument.cpp +@@ -3916,7 +3916,7 @@ nsDocument::InsertChildAt(nsIContent* aKid, uint32_t aIndex, + bool aNotify) + { + if (aKid->IsElement() && GetRootElement()) { +- NS_ERROR("Inserting element child when we already have one"); ++ NS_WARNING("Inserting root element when we already have one"); + return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; + } + + Modified parser/html/nsHtml5Parser.cpp +diff --git a/parser/html/nsHtml5Parser.cpp b/parser/html/nsHtml5Parser.cpp +index a485be4..f28adb4 100644 +--- a/parser/html/nsHtml5Parser.cpp ++++ b/parser/html/nsHtml5Parser.cpp +@@ -237,7 +237,8 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer, + * WillBuildModel to be called before the document has had its + * script global object set. + */ +- mExecutor->WillBuildModel(eDTDMode_unknown); ++ rv = mExecutor->WillBuildModel(eDTDMode_unknown); ++ NS_ENSURE_SUCCESS(rv, rv); + } + + // Return early if the parser has processed EOF +@@ -255,7 +256,7 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer, + } + mDocumentClosed = true; + if (!mBlocked && !mInDocumentWrite) { +- ParseUntilBlocked(); ++ return ParseUntilBlocked(); + } + return NS_OK; + } +@@ -378,7 +379,8 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer, + + if (mTreeBuilder->HasScript()) { + mTreeBuilder->Flush(); // Move ops to the executor +- mExecutor->FlushDocumentWrite(); // run the ops ++ rv = mExecutor->FlushDocumentWrite(); // run the ops ++ NS_ENSURE_SUCCESS(rv, rv); + // Flushing tree ops can cause all sorts of things. + // Return early if the parser got terminated. + if (mExecutor->IsComplete()) { +@@ -437,7 +439,8 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer, + "Buffer wasn't tokenized to completion?"); + // Scripting semantics require a forced tree builder flush here + mTreeBuilder->Flush(); // Move ops to the executor +- mExecutor->FlushDocumentWrite(); // run the ops ++ rv = mExecutor->FlushDocumentWrite(); // run the ops ++ NS_ENSURE_SUCCESS(rv, rv); + } else if (stackBuffer.hasMore()) { + // The buffer wasn't tokenized to completion. Tokenize the untokenized + // content in order to preload stuff. This content will be retokenized +@@ -594,11 +597,13 @@ nsHtml5Parser::IsScriptCreated() + /* End nsIParser */ + + // not from interface +-void ++nsresult + nsHtml5Parser::ParseUntilBlocked() + { +- if (mBlocked || mExecutor->IsComplete() || NS_FAILED(mExecutor->IsBroken())) { +- return; ++ nsresult rv = mExecutor->IsBroken(); ++ NS_ENSURE_SUCCESS(rv, rv); ++ if (mBlocked || mExecutor->IsComplete()) { ++ return NS_OK; + } + NS_ASSERTION(mExecutor->HasStarted(), "Bad life cycle."); + NS_ASSERTION(!mInDocumentWrite, +@@ -611,7 +616,7 @@ nsHtml5Parser::ParseUntilBlocked() + if (mFirstBuffer == mLastBuffer) { + if (mExecutor->IsComplete()) { + // something like cache manisfests stopped the parse in mid-flight +- return; ++ return NS_OK; + } + if (mDocumentClosed) { + NS_ASSERTION(!GetStreamParser(), +@@ -620,8 +625,10 @@ nsHtml5Parser::ParseUntilBlocked() + mTreeBuilder->StreamEnded(); + mTreeBuilder->Flush(); + mExecutor->FlushDocumentWrite(); ++ // The below call does memory cleanup, so call it even if the ++ // parser has been marked as broken. + mTokenizer->end(); +- return; ++ return NS_OK; + } + // never release the last buffer. + NS_ASSERTION(!mLastBuffer->getStart() && !mLastBuffer->getEnd(), +@@ -643,14 +650,14 @@ nsHtml5Parser::ParseUntilBlocked() + NS_ASSERTION(mExecutor->IsInFlushLoop(), + "How did we come here without being in the flush loop?"); + } +- return; // no more data for now but expecting more ++ return NS_OK; // no more data for now but expecting more + } + mFirstBuffer = mFirstBuffer->next; + continue; + } + + if (mBlocked || mExecutor->IsComplete()) { +- return; ++ return NS_OK; + } + + // now we have a non-empty buffer +@@ -667,10 +674,11 @@ nsHtml5Parser::ParseUntilBlocked() + } + if (mTreeBuilder->HasScript()) { + mTreeBuilder->Flush(); +- mExecutor->FlushDocumentWrite(); ++ nsresult rv = mExecutor->FlushDocumentWrite(); ++ NS_ENSURE_SUCCESS(rv, rv); + } + if (mBlocked) { +- return; ++ return NS_OK; + } + } + continue; + Modified parser/html/nsHtml5Parser.h +diff --git a/parser/html/nsHtml5Parser.h b/parser/html/nsHtml5Parser.h +index aff79c7..e2ef2f8 100644 +--- a/parser/html/nsHtml5Parser.h ++++ b/parser/html/nsHtml5Parser.h +@@ -262,7 +262,7 @@ class nsHtml5Parser : public nsIParser, + /** + * Parse until pending data is exhausted or a script blocks the parser + */ +- void ParseUntilBlocked(); ++ nsresult ParseUntilBlocked(); + + private: + + Modified parser/html/nsHtml5StreamParser.cpp +diff --git a/parser/html/nsHtml5StreamParser.cpp b/parser/html/nsHtml5StreamParser.cpp +index 4790568..7e3917b 100644 +--- a/parser/html/nsHtml5StreamParser.cpp ++++ b/parser/html/nsHtml5StreamParser.cpp +@@ -796,7 +796,7 @@ nsHtml5StreamParser::WriteStreamBytes(const uint8_t* aFromSegment, + // NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE. + if (!mLastBuffer) { + NS_WARNING("mLastBuffer should not be null!"); +- MarkAsBroken(); ++ MarkAsBroken(NS_ERROR_NULL_POINTER); + return NS_ERROR_NULL_POINTER; + } + if (mLastBuffer->getEnd() == NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE) { +@@ -902,7 +902,8 @@ nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) + * WillBuildModel to be called before the document has had its + * script global object set. + */ +- mExecutor->WillBuildModel(eDTDMode_unknown); ++ rv = mExecutor->WillBuildModel(eDTDMode_unknown); ++ NS_ENSURE_SUCCESS(rv, rv); + + nsRefPtr newBuf = + nsHtml5OwningUTF16Buffer::FalliblyCreate( +@@ -1003,8 +1004,9 @@ nsHtml5StreamParser::DoStopRequest() + + if (!mUnicodeDecoder) { + uint32_t writeCount; +- if (NS_FAILED(FinalizeSniffing(nullptr, 0, &writeCount, 0))) { +- MarkAsBroken(); ++ nsresult rv; ++ if (NS_FAILED(rv = FinalizeSniffing(nullptr, 0, &writeCount, 0))) { ++ MarkAsBroken(rv); + return; + } + } else if (mFeedChardet) { +@@ -1076,7 +1078,7 @@ nsHtml5StreamParser::DoDataAvailable(const uint8_t* aBuffer, uint32_t aLength) + rv = SniffStreamBytes(aBuffer, aLength, &writeCount); + } + if (NS_FAILED(rv)) { +- MarkAsBroken(); ++ MarkAsBroken(rv); + return; + } + NS_ASSERTION(writeCount == aLength, "Wrong number of stream bytes written/sniffed."); +@@ -1662,13 +1664,13 @@ nsHtml5StreamParser::TimerFlush() + } + + void +-nsHtml5StreamParser::MarkAsBroken() ++nsHtml5StreamParser::MarkAsBroken(nsresult aRv) + { + NS_ASSERTION(IsParserThread(), "Wrong thread!"); + mTokenizerMutex.AssertCurrentThreadOwns(); + + Terminate(); +- mTreeBuilder->MarkAsBroken(); ++ mTreeBuilder->MarkAsBroken(aRv); + mozilla::DebugOnly hadOps = mTreeBuilder->Flush(false); + NS_ASSERTION(hadOps, "Should have had the markAsBroken op!"); + if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) { + Modified parser/html/nsHtml5StreamParser.h +diff --git a/parser/html/nsHtml5StreamParser.h b/parser/html/nsHtml5StreamParser.h +index c7dcbbe..476ef16 100644 +--- a/parser/html/nsHtml5StreamParser.h ++++ b/parser/html/nsHtml5StreamParser.h +@@ -218,7 +218,7 @@ class nsHtml5StreamParser : public nsICharsetDetectionObserver { + } + #endif + +- void MarkAsBroken(); ++ void MarkAsBroken(nsresult aRv); + + /** + * Marks the stream parser as interrupted. If you ever add calls to this + Modified parser/html/nsHtml5TreeBuilderCppSupplement.h +diff --git a/parser/html/nsHtml5TreeBuilderCppSupplement.h b/parser/html/nsHtml5TreeBuilderCppSupplement.h +index 4cd5c7c..1e65394 100644 +--- a/parser/html/nsHtml5TreeBuilderCppSupplement.h ++++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h +@@ -949,14 +949,14 @@ nsHtml5TreeBuilder::DropHandles() + } + + void +-nsHtml5TreeBuilder::MarkAsBroken() ++nsHtml5TreeBuilder::MarkAsBroken(nsresult aRv) + { + if (MOZ_UNLIKELY(mBuilder)) { + MOZ_ASSUME_UNREACHABLE("Must not call this with builder."); + return; + } + mOpQueue.Clear(); // Previous ops don't matter anymore +- mOpQueue.AppendElement()->Init(eTreeOpMarkAsBroken); ++ mOpQueue.AppendElement()->Init(aRv); + } + + void + Modified parser/html/nsHtml5TreeBuilderHSupplement.h +diff --git a/parser/html/nsHtml5TreeBuilderHSupplement.h b/parser/html/nsHtml5TreeBuilderHSupplement.h +index a321e80..8d380eb 100644 +--- a/parser/html/nsHtml5TreeBuilderHSupplement.h ++++ b/parser/html/nsHtml5TreeBuilderHSupplement.h +@@ -223,4 +223,4 @@ + + void errEndWithUnclosedElements(nsIAtom* aName); + +- void MarkAsBroken(); ++ void MarkAsBroken(nsresult aRv); + Modified parser/html/nsHtml5TreeOpExecutor.cpp +diff --git a/parser/html/nsHtml5TreeOpExecutor.cpp b/parser/html/nsHtml5TreeOpExecutor.cpp +index ebcafca..6c52e5f 100644 +--- a/parser/html/nsHtml5TreeOpExecutor.cpp ++++ b/parser/html/nsHtml5TreeOpExecutor.cpp +@@ -411,7 +411,11 @@ nsHtml5TreeOpExecutor::RunFlushLoop() + GetParser()->GetStreamParser(); + // Now parse content left in the document.write() buffer queue if any. + // This may generate tree ops on its own or dequeue a speculation. +- GetParser()->ParseUntilBlocked(); ++ nsresult rv = GetParser()->ParseUntilBlocked(); ++ if (NS_FAILED(rv)) { ++ MarkAsBroken(rv); ++ return; ++ } + } + + if (mOpQueue.IsEmpty()) { +@@ -496,21 +500,24 @@ nsHtml5TreeOpExecutor::RunFlushLoop() + } + } + +-void ++nsresult + nsHtml5TreeOpExecutor::FlushDocumentWrite() + { ++ nsresult rv = IsBroken(); ++ NS_ENSURE_SUCCESS(rv, rv); ++ + FlushSpeculativeLoads(); // Make sure speculative loads never start after the + // corresponding normal loads for the same URLs. + + if (MOZ_UNLIKELY(!mParser)) { + // The parse has ended. + mOpQueue.Clear(); // clear in order to be able to assert in destructor +- return; ++ return rv; + } + + if (mFlushState != eNotFlushing) { + // XXX Can this happen? In case it can, let's avoid crashing. +- return; ++ return rv; + } + + mFlushState = eInFlush; +@@ -545,7 +552,7 @@ nsHtml5TreeOpExecutor::FlushDocumentWrite() + } + NS_ASSERTION(mFlushState == eInDocUpdate, + "Tried to perform tree op outside update batch."); +- nsresult rv = iter->Perform(this, &scriptElement); ++ rv = iter->Perform(this, &scriptElement); + if (NS_FAILED(rv)) { + MarkAsBroken(rv); + break; +@@ -560,13 +567,14 @@ nsHtml5TreeOpExecutor::FlushDocumentWrite() + + if (MOZ_UNLIKELY(!mParser)) { + // Ending the doc update caused a call to nsIParser::Terminate(). +- return; ++ return rv; + } + + if (scriptElement) { + // must be tail call when mFlushState is eNotFlushing + RunScript(scriptElement); + } ++ return rv; + } + + // copied from HTML content sink + Modified parser/html/nsHtml5TreeOpExecutor.h +diff --git a/parser/html/nsHtml5TreeOpExecutor.h b/parser/html/nsHtml5TreeOpExecutor.h +index 9617dcb..1f81448 100644 +--- a/parser/html/nsHtml5TreeOpExecutor.h ++++ b/parser/html/nsHtml5TreeOpExecutor.h +@@ -173,7 +173,7 @@ class nsHtml5TreeOpExecutor : public nsHtml5DocumentBuilder, + + void RunFlushLoop(); + +- void FlushDocumentWrite(); ++ nsresult FlushDocumentWrite(); + + void MaybeSuspend(); + + Modified parser/html/nsHtml5TreeOperation.cpp +diff --git a/parser/html/nsHtml5TreeOperation.cpp b/parser/html/nsHtml5TreeOperation.cpp +index 48b71dc..7ad65247 100644 +--- a/parser/html/nsHtml5TreeOperation.cpp ++++ b/parser/html/nsHtml5TreeOperation.cpp +@@ -214,6 +214,9 @@ nsHtml5TreeOperation::AppendToDocument(nsIContent* aNode, + nsIDocument* doc = aBuilder->GetDocument(); + uint32_t childCount = doc->GetChildCount(); + rv = doc->AppendChildTo(aNode, false); ++ if (rv == NS_ERROR_DOM_HIERARCHY_REQUEST_ERR) { ++ return NS_OK; ++ } + NS_ENSURE_SUCCESS(rv, rv); + nsNodeUtils::ContentInserted(doc, aNode, childCount); + +@@ -739,8 +742,7 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder, + return NS_OK; + } + case eTreeOpMarkAsBroken: { +- aBuilder->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY); +- return NS_OK; ++ return mOne.result; + } + case eTreeOpRunScript: { + nsIContent* node = *(mOne.node); + Modified parser/html/nsHtml5TreeOperation.h +diff --git a/parser/html/nsHtml5TreeOperation.h b/parser/html/nsHtml5TreeOperation.h +index 2727733..06d0274 100644 +--- a/parser/html/nsHtml5TreeOperation.h ++++ b/parser/html/nsHtml5TreeOperation.h +@@ -435,6 +435,15 @@ class nsHtml5TreeOperation { + mFour.integer = aInt; + } + ++ inline void Init(nsresult aRv) ++ { ++ NS_PRECONDITION(mOpCode == eTreeOpUninitialized, ++ "Op code must be uninitialized when initializing."); ++ NS_PRECONDITION(NS_FAILED(aRv), "Initialized tree op with non-failure."); ++ mOpCode = eTreeOpMarkAsBroken; ++ mOne.result = aRv; ++ } ++ + inline void InitAddClass(nsIContentHandle* aNode, const char16_t* aClass) + { + NS_PRECONDITION(mOpCode == eTreeOpUninitialized, +@@ -487,11 +496,12 @@ class nsHtml5TreeOperation { + nsIAtom* atom; + nsHtml5HtmlAttributes* attributes; + nsHtml5DocumentMode mode; +- char16_t* unicharPtr; ++ char16_t* unicharPtr; + char* charPtr; + nsHtml5TreeOperationStringPair* stringPair; + nsAHtml5TreeBuilderState* state; + int32_t integer; ++ nsresult result; + } mOne, mTwo, mThree, mFour; + }; + diff --git a/gnu/packages/patches/icecat-CVE-2014-1593.patch b/gnu/packages/patches/icecat-CVE-2014-1593.patch new file mode 100644 index 0000000000..446920a95f --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2014-1593.patch @@ -0,0 +1,154 @@ +commit a58cea744ac5b93b99a66554e1029b2c7aa3255d +Author: Matthew Gregan +Date: Tue Nov 11 08:58:52 2014 +1300 + + Bug 1085175. r=roc, a=dveditz + + Modified content/media/MediaCache.cpp +diff --git a/content/media/MediaCache.cpp b/content/media/MediaCache.cpp +index 598d905..c99f724 100644 +--- a/content/media/MediaCache.cpp ++++ b/content/media/MediaCache.cpp +@@ -1174,6 +1174,7 @@ MediaCache::Update() + // Figure out where we should be reading from. It's the first + // uncached byte after the current mStreamOffset. + int64_t dataOffset = stream->GetCachedDataEndInternal(stream->mStreamOffset); ++ MOZ_ASSERT(dataOffset >= 0); + + // Compute where we'd actually seek to to read at readOffset + int64_t desiredOffset = dataOffset; +@@ -1702,6 +1703,7 @@ MediaCacheStream::NotifyDataStarted(int64_t aOffset) + ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor()); + NS_WARN_IF_FALSE(aOffset == mChannelOffset, + "Server is giving us unexpected offset"); ++ MOZ_ASSERT(aOffset >= 0); + mChannelOffset = aOffset; + if (mStreamLength >= 0) { + // If we started reading at a certain offset, then for sure +@@ -2118,23 +2120,28 @@ MediaCacheStream::Seek(int32_t aWhence, int64_t aOffset) + return NS_ERROR_FAILURE; + + int64_t oldOffset = mStreamOffset; ++ int64_t newOffset = mStreamOffset; + switch (aWhence) { + case PR_SEEK_END: + if (mStreamLength < 0) + return NS_ERROR_FAILURE; +- mStreamOffset = mStreamLength + aOffset; ++ newOffset = mStreamLength + aOffset; + break; + case PR_SEEK_CUR: +- mStreamOffset += aOffset; ++ newOffset += aOffset; + break; + case PR_SEEK_SET: +- mStreamOffset = aOffset; ++ newOffset = aOffset; + break; + default: + NS_ERROR("Unknown whence"); + return NS_ERROR_FAILURE; + } + ++ if (newOffset < 0) ++ return NS_ERROR_FAILURE; ++ mStreamOffset = newOffset; ++ + CACHE_LOG(PR_LOG_DEBUG, ("Stream %p Seek to %lld", this, (long long)mStreamOffset)); + gMediaCache->NoteSeek(this, oldOffset); + +@@ -2176,11 +2183,10 @@ MediaCacheStream::Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes) + break; + } + size = std::min(size, bytesRemaining); +- // Clamp size until 64-bit file size issues (bug 500784) are fixed. ++ // Clamp size until 64-bit file size issues are fixed. + size = std::min(size, int64_t(INT32_MAX)); + } + +- int32_t bytes; + int32_t cacheBlock = streamBlock < mBlocks.Length() ? mBlocks[streamBlock] : -1; + if (cacheBlock < 0) { + // We don't have a complete cached block here. +@@ -2208,7 +2214,10 @@ MediaCacheStream::Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes) + // We can just use the data in mPartialBlockBuffer. In fact we should + // use it rather than waiting for the block to fill and land in + // the cache. +- bytes = std::min(size, streamWithPartialBlock->mChannelOffset - mStreamOffset); ++ int64_t bytes = std::min(size, streamWithPartialBlock->mChannelOffset - mStreamOffset); ++ // Clamp bytes until 64-bit file size issues are fixed. ++ bytes = std::min(bytes, int64_t(INT32_MAX)); ++ NS_ABORT_IF_FALSE(bytes >= 0 && bytes <= aCount, "Bytes out of range."); + memcpy(aBuffer, + reinterpret_cast(streamWithPartialBlock->mPartialBlockBuffer.get()) + offsetInStreamBlock, bytes); + if (mCurrentMode == MODE_METADATA) { +@@ -2232,6 +2241,7 @@ MediaCacheStream::Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes) + gMediaCache->NoteBlockUsage(this, cacheBlock, mCurrentMode, TimeStamp::Now()); + + int64_t offset = cacheBlock*BLOCK_SIZE + offsetInStreamBlock; ++ int32_t bytes; + NS_ABORT_IF_FALSE(size >= 0 && size <= INT32_MAX, "Size out of range."); + nsresult rv = gMediaCache->ReadCacheFile(offset, aBuffer + count, int32_t(size), &bytes); + if (NS_FAILED(rv)) { +@@ -2268,9 +2278,7 @@ MediaCacheStream::ReadAt(int64_t aOffset, char* aBuffer, + } + + nsresult +-MediaCacheStream::ReadFromCache(char* aBuffer, +- int64_t aOffset, +- int64_t aCount) ++MediaCacheStream::ReadFromCache(char* aBuffer, int64_t aOffset, int64_t aCount) + { + ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor()); + if (mClosed) +@@ -2292,7 +2300,7 @@ MediaCacheStream::ReadFromCache(char* aBuffer, + return NS_ERROR_FAILURE; + } + size = std::min(size, bytesRemaining); +- // Clamp size until 64-bit file size issues (bug 500784) are fixed. ++ // Clamp size until 64-bit file size issues are fixed. + size = std::min(size, int64_t(INT32_MAX)); + } + +@@ -2303,7 +2311,10 @@ MediaCacheStream::ReadFromCache(char* aBuffer, + // We can just use the data in mPartialBlockBuffer. In fact we should + // use it rather than waiting for the block to fill and land in + // the cache. +- bytes = std::min(size, mChannelOffset - streamOffset); ++ // Clamp bytes until 64-bit file size issues are fixed. ++ int64_t toCopy = std::min(size, mChannelOffset - streamOffset); ++ bytes = std::min(toCopy, int64_t(INT32_MAX)); ++ NS_ABORT_IF_FALSE(bytes >= 0 && bytes <= toCopy, "Bytes out of range."); + memcpy(aBuffer + count, + reinterpret_cast(mPartialBlockBuffer.get()) + offsetInStreamBlock, bytes); + } else { + Modified media/libnestegg/include/nestegg-stdint.h +diff --git a/media/libnestegg/include/nestegg-stdint.h b/media/libnestegg/include/nestegg-stdint.h +index 599a7a5..c315991 100644 +--- a/media/libnestegg/include/nestegg-stdint.h ++++ b/media/libnestegg/include/nestegg-stdint.h +@@ -1,6 +1,9 @@ + #ifdef _WIN32 + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; ++#if !defined(INT64_MAX) ++#define INT64_MAX 9223372036854775807LL ++#endif + #else + #include + #endif + Modified media/libnestegg/src/nestegg.c +diff --git a/media/libnestegg/src/nestegg.c b/media/libnestegg/src/nestegg.c +index 8813cf2..56884d7 100644 +--- a/media/libnestegg/src/nestegg.c ++++ b/media/libnestegg/src/nestegg.c +@@ -1950,6 +1950,9 @@ nestegg_offset_seek(nestegg * ctx, uint64_t offset) + { + int r; + ++ if (offset > INT64_MAX) ++ return -1; ++ + /* Seek and set up parser state for segment-level element (Cluster). */ + r = ne_io_seek(ctx->io, offset, NESTEGG_SEEK_SET); + if (r != 0) diff --git a/gnu/packages/patches/icecat-CVE-2014-1594.patch b/gnu/packages/patches/icecat-CVE-2014-1594.patch new file mode 100644 index 0000000000..e5ce7b069b --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2014-1594.patch @@ -0,0 +1,34 @@ +commit 7a8497c0df722b1ed145b99a82c71ed1f7b1d6ce +Author: Markus Stange +Date: Thu Oct 9 21:26:27 2014 -0400 + + Bug 1074280 - Use AsContainerLayer() in order to avoid a bad cast. r=roc, a=bkerensa + + Modified gfx/layers/basic/BasicLayerManager.cpp +diff --git a/gfx/layers/basic/BasicLayerManager.cpp b/gfx/layers/basic/BasicLayerManager.cpp +index 5a3a1f6..ff42bc0 100644 +--- a/gfx/layers/basic/BasicLayerManager.cpp ++++ b/gfx/layers/basic/BasicLayerManager.cpp +@@ -901,18 +901,17 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget, + RenderTraceScope trace("BasicLayerManager::PaintLayer", "707070"); + + const nsIntRect* clipRect = aLayer->GetEffectiveClipRect(); +- // aLayer might not be a container layer, but if so we take care not to use +- // the container variable +- BasicContainerLayer* container = static_cast(aLayer); +- bool needsGroup = aLayer->GetFirstChild() && ++ BasicContainerLayer* container = ++ static_cast(aLayer->AsContainerLayer()); ++ bool needsGroup = container && + container->UseIntermediateSurface(); + BasicImplData* data = ToData(aLayer); + bool needsClipToVisibleRegion = + data->GetClipToVisibleRegion() && !aLayer->AsThebesLayer(); +- NS_ASSERTION(needsGroup || !aLayer->GetFirstChild() || ++ NS_ASSERTION(needsGroup || !container || + container->GetOperator() == CompositionOp::OP_OVER, + "non-OVER operator should have forced UseIntermediateSurface"); +- NS_ASSERTION(!aLayer->GetFirstChild() || !aLayer->GetMaskLayer() || ++ NS_ASSERTION(!container || !aLayer->GetMaskLayer() || + container->UseIntermediateSurface(), + "ContainerLayer with mask layer should force UseIntermediateSurface");