aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark H Weaver <mhw@netris.org>2014-12-15 18:27:56 -0500
committerMark H Weaver <mhw@netris.org>2014-12-15 20:42:53 -0500
commit9f8552fab59a250a0c099062937fa057ea6b38b3 (patch)
treefa1fa890ecaf2a77c8ec91fbeb913350d6ad5608
parentbea26837e8f010efde3fdf584f2a158676779ef3 (diff)
downloadgnu-guix-9f8552fab59a250a0c099062937fa057ea6b38b3.tar
gnu-guix-9f8552fab59a250a0c099062937fa057ea6b38b3.tar.gz
gnu: icecat: Apply security updates for CVE-2014-{1587,1590,1592,1593,1594}.
* 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: New files. * gnu-system.am (dist_patch_DATA): Add them. * gnu/packages/gnuzilla.scm (icecat): Add them.
-rw-r--r--gnu-system.am9
-rw-r--r--gnu/packages/gnuzilla.scm12
-rw-r--r--gnu/packages/patches/icecat-CVE-2014-1587-bug-1042567.patch30
-rw-r--r--gnu/packages/patches/icecat-CVE-2014-1587-bug-1072847.patch19
-rw-r--r--gnu/packages/patches/icecat-CVE-2014-1587-bug-1079729.patch191
-rw-r--r--gnu/packages/patches/icecat-CVE-2014-1587-bug-1080312.patch308
-rw-r--r--gnu/packages/patches/icecat-CVE-2014-1587-bug-1089207.patch119
-rw-r--r--gnu/packages/patches/icecat-CVE-2014-1590.patch33
-rw-r--r--gnu/packages/patches/icecat-CVE-2014-1592.patch400
-rw-r--r--gnu/packages/patches/icecat-CVE-2014-1593.patch154
-rw-r--r--gnu/packages/patches/icecat-CVE-2014-1594.patch34
11 files changed, 1308 insertions, 1 deletions
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 <jorendorff@mozilla.com>
+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 <jmuizelaar@mozilla.com>
+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 <rjesup@jesup.org>
+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 <rjesup@jesup.org>
+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 <sys/types.h>
++#if !defined (__Userspace_os_Windows)
++#include <sys/wait.h>
++#include <unistd.h>
++#include <pthread.h>
++#endif
++#if defined(__Userspace_os_NaCl)
++#include <sys/select.h>
++#endif
++#include <stdlib.h>
++#include <string.h>
++#include <stdio.h>
++#include <errno.h>
++#include <netinet/sctp_sysctl.h>
++#include <netinet/sctp_pcb.h>
++#else
+ #include <netinet/sctp_os.h>
+ #include <netinet/sctp_callout.h>
+ #include <netinet/sctp_pcb.h>
++#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 <netinet/sctp_timer.h>
+ #include <netinet/sctp_auth.h>
+ #include <netinet/sctp_bsd_addr.h>
++#if defined(__Userspace__)
++#include <netinet/sctp_callout.h>
++#endif
+ #if !defined(__Userspace_os_Windows)
+ #include <netinet/udp.h>
+ #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 <sys/types.h>
+-#if !defined (__Userspace_os_Windows)
+-#include <sys/wait.h>
+-#include <unistd.h>
+-#include <pthread.h>
+-#endif
+-#include <stdlib.h>
+-#include <string.h>
+-#include <stdio.h>
+-#include <errno.h>
+-#include <netinet/sctp_pcb.h>
+-#include <netinet/sctp_sysctl.h>
+-#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] <drno@ohlmeier.org>
+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<char *>(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 <Olli.Pettay@helsinki.fi>
+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<nsIXPConnectWrappedJS> 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 <hsivonen@hsivonen.fi>
+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<nsHtml5OwningUTF16Buffer> 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<bool> 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 <kinetik@flim.org>
+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<int64_t>(size, streamWithPartialBlock->mChannelOffset - mStreamOffset);
++ int64_t bytes = std::min<int64_t>(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<char*>(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<int64_t>(size, mChannelOffset - streamOffset);
++ // Clamp bytes until 64-bit file size issues are fixed.
++ int64_t toCopy = std::min<int64_t>(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<char*>(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 <stdint.h>
+ #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 <mstange@themasta.com>
+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<BasicContainerLayer*>(aLayer);
+- bool needsGroup = aLayer->GetFirstChild() &&
++ BasicContainerLayer* container =
++ static_cast<BasicContainerLayer*>(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");