summary refs log tree commit diff
path: root/gnu/packages/patches
diff options
context:
space:
mode:
authorMark H Weaver <mhw@netris.org>2015-12-17 12:07:13 -0500
committerMark H Weaver <mhw@netris.org>2015-12-17 14:12:06 -0500
commit3faf214a0b58c10e9838fcbf59f139172fe4a871 (patch)
tree5530a388f5930964a02bb26ae010abb6140de845 /gnu/packages/patches
parentcbbe1a1c2c7ca86e348656ae3b7197d53c2527f2 (diff)
downloadguix-3faf214a0b58c10e9838fcbf59f139172fe4a871.tar.gz
gnu: icecat: Add fixes for several security flaws.
* gnu/packages/patches/icecat-CVE-2015-7201-pt1.patch,
  gnu/packages/patches/icecat-CVE-2015-7201-pt2.patch,
  gnu/packages/patches/icecat-CVE-2015-7201-pt3.patch,
  gnu/packages/patches/icecat-CVE-2015-7205.patch,
  gnu/packages/patches/icecat-CVE-2015-7210.patch,
  gnu/packages/patches/icecat-CVE-2015-7212.patch,
  gnu/packages/patches/icecat-CVE-2015-7213-pt1.patch,
  gnu/packages/patches/icecat-CVE-2015-7213-pt2.patch,
  gnu/packages/patches/icecat-CVE-2015-7214.patch,
  gnu/packages/patches/icecat-CVE-2015-7222-pt1.patch,
  gnu/packages/patches/icecat-CVE-2015-7222-pt2.patch,
  gnu/packages/patches/icecat-CVE-2015-7222-pt3.patch: New files.
* gnu-system.am (dist_patch_DATA): Add them.
* gnu/packages/gnuzilla.scm (icecat)[source]: Add patches.
Diffstat (limited to 'gnu/packages/patches')
-rw-r--r--gnu/packages/patches/icecat-CVE-2015-7201-pt1.patch123
-rw-r--r--gnu/packages/patches/icecat-CVE-2015-7201-pt2.patch29
-rw-r--r--gnu/packages/patches/icecat-CVE-2015-7201-pt3.patch35
-rw-r--r--gnu/packages/patches/icecat-CVE-2015-7205.patch84
-rw-r--r--gnu/packages/patches/icecat-CVE-2015-7210.patch47
-rw-r--r--gnu/packages/patches/icecat-CVE-2015-7212.patch364
-rw-r--r--gnu/packages/patches/icecat-CVE-2015-7213-pt1.patch32
-rw-r--r--gnu/packages/patches/icecat-CVE-2015-7213-pt2.patch27
-rw-r--r--gnu/packages/patches/icecat-CVE-2015-7214.patch47
-rw-r--r--gnu/packages/patches/icecat-CVE-2015-7222-pt1.patch112
-rw-r--r--gnu/packages/patches/icecat-CVE-2015-7222-pt2.patch34
-rw-r--r--gnu/packages/patches/icecat-CVE-2015-7222-pt3.patch37
12 files changed, 971 insertions, 0 deletions
diff --git a/gnu/packages/patches/icecat-CVE-2015-7201-pt1.patch b/gnu/packages/patches/icecat-CVE-2015-7201-pt1.patch
new file mode 100644
index 0000000000..0fcfe9b409
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2015-7201-pt1.patch
@@ -0,0 +1,123 @@
+From e2bbd632e220be7626efd34acb9a517430d36004 Mon Sep 17 00:00:00 2001
+From: Andrew Comminos <andrew@comminos.com>
+Date: Fri, 23 Oct 2015 21:35:16 -0700
+Subject: [PATCH] Bug 1203135 - Terminate linking if maximum vertex attribute
+ count is exceeded on Mesa. r=jgilbert, a=ritu
+
+--HG--
+extra : source : 8021382da9722db0ad97ebd93698b69a74f0d9b0
+extra : intermediate-source : 90eff805d2810e9d9ea88f6869335b0500b1a536
+---
+ dom/canvas/WebGLProgram.cpp         | 28 ++++++++++++++++++----------
+ dom/canvas/WebGLShader.cpp          | 10 ++++++++++
+ dom/canvas/WebGLShader.h            |  1 +
+ dom/canvas/WebGLShaderValidator.cpp |  6 ++++++
+ dom/canvas/WebGLShaderValidator.h   |  1 +
+ 5 files changed, 36 insertions(+), 10 deletions(-)
+
+diff --git a/dom/canvas/WebGLProgram.cpp b/dom/canvas/WebGLProgram.cpp
+index 78f7413..0e056e8 100644
+--- a/dom/canvas/WebGLProgram.cpp
++++ b/dom/canvas/WebGLProgram.cpp
+@@ -569,18 +569,26 @@ WebGLProgram::LinkProgram()
+     gl::GLContext* gl = mContext->gl;
+     gl->MakeCurrent();
+ 
+-    // Bug 777028: Mesa can't handle more than 16 samplers per program,
+-    // counting each array entry.
+-    size_t numSamplerUniforms_upperBound = mVertShader->CalcNumSamplerUniforms() +
+-                                           mFragShader->CalcNumSamplerUniforms();
+     if (gl->WorkAroundDriverBugs() &&
+-        mContext->mIsMesa &&
+-        numSamplerUniforms_upperBound > 16)
++        mContext->mIsMesa)
+     {
+-        mLinkLog.AssignLiteral("Programs with more than 16 samplers are disallowed on"
+-                               " Mesa drivers to avoid crashing.");
+-        mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading());
+-        return false;
++        // Bug 777028: Mesa can't handle more than 16 samplers per program,
++        // counting each array entry.
++        size_t numSamplerUniforms_upperBound = mVertShader->CalcNumSamplerUniforms() +
++                                               mFragShader->CalcNumSamplerUniforms();
++        if (numSamplerUniforms_upperBound > 16) {
++            mLinkLog.AssignLiteral("Programs with more than 16 samplers are disallowed on"
++                                   " Mesa drivers to avoid crashing.");
++            mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading());
++            return false;
++        }
++
++        // Bug 1203135: Mesa crashes internally if we exceed the reported maximum attribute count.
++        if (mVertShader->NumAttributes() > mContext->MaxVertexAttribs()) {
++            mLinkLog.AssignLiteral("Number of attributes exceeds Mesa's reported max attribute count.");
++            mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading());
++            return false;
++        }
+     }
+ 
+     // Bind the attrib locations.
+diff --git a/dom/canvas/WebGLShader.cpp b/dom/canvas/WebGLShader.cpp
+index 85a3809..bab4157 100644
+--- a/dom/canvas/WebGLShader.cpp
++++ b/dom/canvas/WebGLShader.cpp
+@@ -299,6 +299,16 @@ WebGLShader::CalcNumSamplerUniforms() const
+     return 0;
+ }
+ 
++size_t
++WebGLShader::NumAttributes() const
++{
++    if (mValidator)
++        return mValidator->NumAttributes();
++
++    // TODO
++    return 0;
++}
++
+ void
+ WebGLShader::BindAttribLocation(GLuint prog, const nsCString& userName,
+                                 GLuint index) const
+diff --git a/dom/canvas/WebGLShader.h b/dom/canvas/WebGLShader.h
+index 698e30c..2c80b16a 100644
+--- a/dom/canvas/WebGLShader.h
++++ b/dom/canvas/WebGLShader.h
+@@ -45,6 +45,7 @@ public:
+     // Util funcs
+     bool CanLinkTo(const WebGLShader* prev, nsCString* const out_log) const;
+     size_t CalcNumSamplerUniforms() const;
++    size_t NumAttributes() const;
+     void BindAttribLocation(GLuint prog, const nsCString& userName, GLuint index) const;
+     bool FindAttribUserNameByMappedName(const nsACString& mappedName,
+                                         nsDependentCString* const out_userName) const;
+diff --git a/dom/canvas/WebGLShaderValidator.cpp b/dom/canvas/WebGLShaderValidator.cpp
+index 80005e2..8bedf88 100644
+--- a/dom/canvas/WebGLShaderValidator.cpp
++++ b/dom/canvas/WebGLShaderValidator.cpp
+@@ -274,6 +274,12 @@ ShaderValidator::CalcNumSamplerUniforms() const
+     return accum;
+ }
+ 
++size_t
++ShaderValidator::NumAttributes() const
++{
++  return ShGetAttributes(mHandle)->size();
++}
++
+ // Attribs cannot be structs or arrays, and neither can vertex inputs in ES3.
+ // Therefore, attrib names are always simple.
+ bool
+diff --git a/dom/canvas/WebGLShaderValidator.h b/dom/canvas/WebGLShaderValidator.h
+index 35db2f1..1f794bf0 100644
+--- a/dom/canvas/WebGLShaderValidator.h
++++ b/dom/canvas/WebGLShaderValidator.h
+@@ -41,6 +41,7 @@ public:
+     void GetOutput(nsACString* out) const;
+     bool CanLinkTo(const ShaderValidator* prev, nsCString* const out_log) const;
+     size_t CalcNumSamplerUniforms() const;
++    size_t NumAttributes() const;
+ 
+     bool FindAttribUserNameByMappedName(const std::string& mappedName,
+                                         const std::string** const out_userName) const;
+-- 
+2.6.3
+
diff --git a/gnu/packages/patches/icecat-CVE-2015-7201-pt2.patch b/gnu/packages/patches/icecat-CVE-2015-7201-pt2.patch
new file mode 100644
index 0000000000..3764371a11
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2015-7201-pt2.patch
@@ -0,0 +1,29 @@
+From f02e3252391f5fa79916e4c8f30b3d8340d06cc7 Mon Sep 17 00:00:00 2001
+From: "Carsten \"Tomcat\" Book" <cbook@mozilla.com>
+Date: Tue, 8 Dec 2015 12:38:15 +0100
+Subject: [PATCH] Bug 1225250 - fix stride on SourceSurfaceSkia when
+ initialized from GPU texture. r=jmuizelaar, a=lizzard
+
+---
+ gfx/2d/SourceSurfaceSkia.cpp | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/gfx/2d/SourceSurfaceSkia.cpp b/gfx/2d/SourceSurfaceSkia.cpp
+index 4b95bc2..d7e0714 100644
+--- a/gfx/2d/SourceSurfaceSkia.cpp
++++ b/gfx/2d/SourceSurfaceSkia.cpp
+@@ -110,8 +110,10 @@ SourceSurfaceSkia::InitFromTexture(DrawTargetSkia* aOwner,
+   GrTexture *skiaTexture = aOwner->mGrContext->wrapBackendTexture(skiaTexGlue);
+   SkImageInfo imgInfo = SkImageInfo::Make(aSize.width, aSize.height, GfxFormatToSkiaColorType(aFormat), kOpaque_SkAlphaType);
+   SkGrPixelRef *texRef = new SkGrPixelRef(imgInfo, skiaTexture, false);
+-  mBitmap.setInfo(imgInfo, aSize.width*aSize.height*4);
++  mBitmap.setInfo(imgInfo);
+   mBitmap.setPixelRef(texRef);
++  mFormat = aFormat;
++  mStride = mBitmap.rowBytes();
+ 
+   mDrawTarget = aOwner;
+   return true;
+-- 
+2.6.3
+
diff --git a/gnu/packages/patches/icecat-CVE-2015-7201-pt3.patch b/gnu/packages/patches/icecat-CVE-2015-7201-pt3.patch
new file mode 100644
index 0000000000..022ab5cc16
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2015-7201-pt3.patch
@@ -0,0 +1,35 @@
+From 567a97b6347ac8c2b93ec788c437b7e9bb23ef75 Mon Sep 17 00:00:00 2001
+From: Edwin Flores <eflores@mozilla.com>
+Date: Wed, 2 Dec 2015 16:15:29 +0100
+Subject: [PATCH] Bug 1224100 - Initialize padding to 0 in Downscaler. r=seth,
+ a=sledru
+
+---
+ image/src/Downscaler.cpp | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/image/src/Downscaler.cpp b/image/src/Downscaler.cpp
+index 24ecfda..2a7acfd 100644
+--- a/image/src/Downscaler.cpp
++++ b/image/src/Downscaler.cpp
+@@ -86,11 +86,16 @@ Downscaler::BeginFrame(const nsIntSize& aOriginalSize,
+                                mTargetSize.height, mYFilter.get());
+ 
+   // Allocate the buffer, which contains scanlines of the original image.
+-  mRowBuffer = MakeUnique<uint8_t[]>(mOriginalSize.width * sizeof(uint32_t));
++  size_t bufferLen = mOriginalSize.width * sizeof(uint32_t);
++  mRowBuffer = MakeUnique<uint8_t[]>(bufferLen);
+   if (MOZ_UNLIKELY(!mRowBuffer)) {
+     return NS_ERROR_OUT_OF_MEMORY;
+   }
+ 
++  // Zero buffer to keep valgrind happy.
++  memset(mRowBuffer.get(), 0, bufferLen);
++
++
+   // Allocate the window, which contains horizontally downscaled scanlines. (We
+   // can store scanlines which are already downscale because our downscaling
+   // filter is separable.)
+-- 
+2.6.3
+
diff --git a/gnu/packages/patches/icecat-CVE-2015-7205.patch b/gnu/packages/patches/icecat-CVE-2015-7205.patch
new file mode 100644
index 0000000000..620fa0d6bd
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2015-7205.patch
@@ -0,0 +1,84 @@
+From 20df7b0b3f3e7dd201c9811bbb1e6515da8da359 Mon Sep 17 00:00:00 2001
+From: Randell Jesup <rjesup@jesup.org>
+Date: Thu, 5 Nov 2015 10:17:29 -0500
+Subject: [PATCH] Bug 1220493 - validate RTP packets against underflows.
+ r=pkerr a=sylvestre
+
+--HG--
+extra : source : 575d3aa376b1c8e7507d94833f7b74bf963127cb
+extra : intermediate-source : 2c1b396ef5c3e2424fb9af56d86ebf6f6551a997
+---
+ .../webrtc/modules/rtp_rtcp/source/rtp_utility.cc  | 26 ++++++++++++----------
+ 1 file changed, 14 insertions(+), 12 deletions(-)
+
+diff --git a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_utility.cc b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_utility.cc
+index 9334b23..80cf55a 100644
+--- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_utility.cc
++++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_utility.cc
+@@ -338,12 +338,6 @@ bool RtpHeaderParser::Parse(RTPHeader& header,
+     return false;
+   }
+ 
+-  const uint8_t CSRCocts = CC * 4;
+-
+-  if ((ptr + CSRCocts) > _ptrRTPDataEnd) {
+-    return false;
+-  }
+-
+   header.markerBit      = M;
+   header.payloadType    = PT;
+   header.sequenceNumber = sequenceNumber;
+@@ -352,6 +346,14 @@ bool RtpHeaderParser::Parse(RTPHeader& header,
+   header.numCSRCs       = CC;
+   header.paddingLength  = P ? *(_ptrRTPDataEnd - 1) : 0;
+ 
++  // 12 == sizeof(RFC rtp header) == kRtpMinParseLength, each CSRC=4 bytes
++  header.headerLength   = 12 + (CC * 4);
++  // not a full validation, just safety against underflow.  Padding must
++  // start after the header.  We can have 0 payload bytes left, note.
++  if (header.paddingLength + header.headerLength > length) {
++    return false;
++  }
++
+   for (unsigned int i = 0; i < CC; ++i) {
+     uint32_t CSRC = *ptr++ << 24;
+     CSRC += *ptr++ << 16;
+@@ -359,8 +361,7 @@ bool RtpHeaderParser::Parse(RTPHeader& header,
+     CSRC += *ptr++;
+     header.arrOfCSRCs[i] = CSRC;
+   }
+-
+-  header.headerLength   = 12 + CSRCocts;
++  assert((ptr - _ptrRTPDataBegin) == header.headerLength);
+ 
+   // If in effect, MAY be omitted for those packets for which the offset
+   // is zero.
+@@ -385,8 +386,9 @@ bool RtpHeaderParser::Parse(RTPHeader& header,
+     |                        header extension                       |
+     |                             ....                              |
+     */
+-    const ptrdiff_t remain = _ptrRTPDataEnd - ptr;
+-    if (remain < 4) {
++    // earlier test ensures we have at least paddingLength bytes left
++    const ptrdiff_t remain = (_ptrRTPDataEnd - ptr) - header.paddingLength;
++    if (remain < 4) { // minimum header extension length = 32 bits
+       return false;
+     }
+ 
+@@ -395,11 +397,11 @@ bool RtpHeaderParser::Parse(RTPHeader& header,
+     uint16_t definedByProfile = *ptr++ << 8;
+     definedByProfile += *ptr++;
+ 
+-    uint16_t XLen = *ptr++ << 8;
++    size_t XLen = *ptr++ << 8;
+     XLen += *ptr++; // in 32 bit words
+     XLen *= 4; // in octs
+ 
+-    if (remain < (4 + XLen)) {
++    if (remain < (4 + XLen)) { // we already accounted for padding
+       return false;
+     }
+     if (definedByProfile == kRtpOneByteHeaderExtensionId) {
+-- 
+2.6.3
+
diff --git a/gnu/packages/patches/icecat-CVE-2015-7210.patch b/gnu/packages/patches/icecat-CVE-2015-7210.patch
new file mode 100644
index 0000000000..eab57021db
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2015-7210.patch
@@ -0,0 +1,47 @@
+From 4e0cd9ba4924869f91be0e7c8cf666182bb75f90 Mon Sep 17 00:00:00 2001
+From: "Byron Campen [:bwc]" <docfaraday@gmail.com>
+Date: Wed, 28 Oct 2015 12:48:17 -0500
+Subject: [PATCH] Bug 1218326 - Prevent datachannel operations on closed
+ PeerConnections. r=jesup a=sylvestre
+
+--HG--
+extra : source : a7637b62d9b5ab73f58e5aa3c663d7d35b624826
+extra : intermediate-source : d8f0412f38f75040064157d8d2b0140df21600e6
+---
+ media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+index c3d8d26..fe86ff7 100644
+--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
++++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+@@ -1004,7 +1004,7 @@ PeerConnectionImpl::GetIdentity() const
+ NS_IMETHODIMP
+ PeerConnectionImpl::EnsureDataConnection(uint16_t aNumstreams)
+ {
+-  PC_AUTO_ENTER_API_CALL_NO_CHECK();
++  PC_AUTO_ENTER_API_CALL(false);
+ 
+ #ifdef MOZILLA_INTERNAL_API
+   if (mDataConnection) {
+@@ -1102,7 +1102,7 @@ PeerConnectionImpl::GetDatachannelParameters(
+ nsresult
+ PeerConnectionImpl::InitializeDataChannel()
+ {
+-  PC_AUTO_ENTER_API_CALL_NO_CHECK();
++  PC_AUTO_ENTER_API_CALL(false);
+   CSFLogDebug(logTag, "%s", __FUNCTION__);
+ 
+   const JsepApplicationCodecDescription* codec;
+@@ -1184,7 +1184,7 @@ PeerConnectionImpl::CreateDataChannel(const nsAString& aLabel,
+                                       uint16_t aStream,
+                                       nsDOMDataChannel** aRetval)
+ {
+-  PC_AUTO_ENTER_API_CALL_NO_CHECK();
++  PC_AUTO_ENTER_API_CALL(false);
+   MOZ_ASSERT(aRetval);
+ 
+ #ifdef MOZILLA_INTERNAL_API
+-- 
+2.6.3
+
diff --git a/gnu/packages/patches/icecat-CVE-2015-7212.patch b/gnu/packages/patches/icecat-CVE-2015-7212.patch
new file mode 100644
index 0000000000..7bda486ff7
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2015-7212.patch
@@ -0,0 +1,364 @@
+From 595e3a152ff2912a950defd0ef4b5f659135b03a Mon Sep 17 00:00:00 2001
+From: Nicolas Silva <nsilva@mozilla.com>
+Date: Wed, 18 Nov 2015 16:59:11 +0100
+Subject: [PATCH] Bug 1222809 - Don't try to allocate unreasonably large
+ textures. r=Bas, a=sylvestre
+
+---
+ gfx/2d/2D.h                             | 25 ++++++++++--
+ gfx/2d/Factory.cpp                      | 67 ++++++++++++++++++++++++++++-----
+ gfx/layers/ImageDataSerializer.cpp      | 21 ++++++-----
+ gfx/layers/YCbCrImageDataSerializer.cpp |  7 ++++
+ gfx/layers/client/TextureClient.cpp     | 12 ++++++
+ gfx/thebes/gfxPlatform.cpp              | 15 ++++++--
+ gfx/thebes/gfxPrefs.h                   |  3 ++
+ 7 files changed, 124 insertions(+), 26 deletions(-)
+
+diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h
+index cf35bb2..b1e0e3e 100644
+--- a/gfx/2d/2D.h
++++ b/gfx/2d/2D.h
+@@ -1082,22 +1082,41 @@ struct TileSet
+   size_t mTileCount;
+ };
+ 
++struct Config {
++  LogForwarder* mLogForwarder;
++  int32_t mMaxTextureSize;
++  int32_t mMaxAllocSize;
++
++  Config()
++  : mLogForwarder(nullptr)
++  , mMaxTextureSize(8192)
++  , mMaxAllocSize(52000000)
++  {}
++};
++
+ class GFX2D_API Factory
+ {
+ public:
++  static void Init(const Config& aConfig);
++  static void ShutDown();
++
+   static bool HasSSE2();
+ 
+   /** Make sure that the given dimensions don't overflow a 32-bit signed int
+    * using 4 bytes per pixel; optionally, make sure that either dimension
+    * doesn't exceed the given limit.
+    */
+-  static bool CheckSurfaceSize(const IntSize &sz, int32_t limit = 0);
++  static bool CheckSurfaceSize(const IntSize &sz,
++                               int32_t limit = 0,
++                               int32_t allocLimit = 0);
+ 
+   /** Make sure the given dimension satisfies the CheckSurfaceSize and is
+    * within 8k limit.  The 8k value is chosen a bit randomly.
+    */
+   static bool ReasonableSurfaceSize(const IntSize &aSize);
+ 
++  static bool AllowedSurfaceSize(const IntSize &aSize);
++
+   static TemporaryRef<DrawTarget> CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat = nullptr);
+ 
+   static TemporaryRef<DrawTarget>
+@@ -1171,10 +1190,10 @@ public:
+ 
+   static uint32_t GetMaxSurfaceSize(BackendType aType);
+ 
+-  static LogForwarder* GetLogForwarder() { return mLogForwarder; }
++  static LogForwarder* GetLogForwarder() { return sConfig ? sConfig->mLogForwarder : nullptr; }
+ 
+ private:
+-  static LogForwarder* mLogForwarder;
++  static Config* sConfig;
+ public:
+ 
+ #ifdef USE_SKIA_GPU
+diff --git a/gfx/2d/Factory.cpp b/gfx/2d/Factory.cpp
+index 948d3c3..6750c28 100644
+--- a/gfx/2d/Factory.cpp
++++ b/gfx/2d/Factory.cpp
+@@ -188,6 +188,35 @@ ID2D1Device *Factory::mD2D1Device;
+ 
+ DrawEventRecorder *Factory::mRecorder;
+ 
++mozilla::gfx::Config* Factory::sConfig = nullptr;
++
++void
++Factory::Init(const Config& aConfig)
++{
++  MOZ_ASSERT(!sConfig);
++  sConfig = new Config(aConfig);
++
++  // Make sure we don't completely break rendering because of a typo in the
++  // pref or whatnot.
++  const int32_t kMinAllocPref = 10000000;
++  const int32_t kMinSizePref = 2048;
++  if (sConfig->mMaxAllocSize < kMinAllocPref) {
++    sConfig->mMaxAllocSize = kMinAllocPref;
++  }
++  if (sConfig->mMaxTextureSize < kMinSizePref) {
++    sConfig->mMaxTextureSize = kMinSizePref;
++  }
++}
++
++void
++Factory::ShutDown()
++{
++  if (sConfig) {
++    delete sConfig;
++    sConfig = nullptr;
++  }
++}
++
+ bool
+ Factory::HasSSE2()
+ {
+@@ -222,11 +251,25 @@ inline int LoggerOptionsBasedOnSize(const IntSize& aSize)
+ bool
+ Factory::ReasonableSurfaceSize(const IntSize &aSize)
+ {
+-  return Factory::CheckSurfaceSize(aSize,8192);
++  return Factory::CheckSurfaceSize(aSize, 8192);
++}
++
++bool
++Factory::AllowedSurfaceSize(const IntSize &aSize)
++{
++  if (sConfig) {
++    return Factory::CheckSurfaceSize(aSize,
++                                     sConfig->mMaxTextureSize,
++                                     sConfig->mMaxAllocSize);
++  }
++
++  return CheckSurfaceSize(aSize);
+ }
+ 
+ bool
+-Factory::CheckSurfaceSize(const IntSize &sz, int32_t limit)
++Factory::CheckSurfaceSize(const IntSize &sz,
++                          int32_t extentLimit,
++                          int32_t allocLimit)
+ {
+   if (sz.width <= 0 || sz.height <= 0) {
+     gfxDebug() << "Surface width or height <= 0!";
+@@ -234,8 +277,8 @@ Factory::CheckSurfaceSize(const IntSize &sz, int32_t limit)
+   }
+ 
+   // reject images with sides bigger than limit
+-  if (limit && (sz.width > limit || sz.height > limit)) {
+-    gfxDebug() << "Surface size too large (exceeds caller's limit)!";
++  if (extentLimit && (sz.width > extentLimit || sz.height > extentLimit)) {
++    gfxDebug() << "Surface size too large (exceeds extent limit)!";
+     return false;
+   }
+ 
+@@ -267,13 +310,18 @@ Factory::CheckSurfaceSize(const IntSize &sz, int32_t limit)
+     return false;
+   }
+ 
++  if (allocLimit && allocLimit < numBytes.value()) {
++    gfxDebug() << "Surface size too large (exceeds allocation limit)!";
++    return false;
++  }
++
+   return true;
+ }
+ 
+ TemporaryRef<DrawTarget>
+ Factory::CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat)
+ {
+-  if (!CheckSurfaceSize(aSize)) {
++  if (!AllowedSurfaceSize(aSize)) {
+     gfxCriticalError(LoggerOptionsBasedOnSize(aSize)) << "Failed to allocate a surface due to invalid size " << aSize;
+     return nullptr;
+   }
+@@ -364,7 +412,7 @@ Factory::CreateDrawTargetForData(BackendType aBackend,
+                                  SurfaceFormat aFormat)
+ {
+   MOZ_ASSERT(aData);
+-  if (!CheckSurfaceSize(aSize)) {
++  if (!AllowedSurfaceSize(aSize)) {
+     gfxCriticalError(LoggerOptionsBasedOnSize(aSize)) << "Failed to allocate a surface due to invalid size " << aSize;
+     return nullptr;
+   }
+@@ -835,7 +883,7 @@ Factory::CreateDataSourceSurface(const IntSize &aSize,
+                                  SurfaceFormat aFormat,
+                                  bool aZero)
+ {
+-  if (!CheckSurfaceSize(aSize)) {
++  if (!AllowedSurfaceSize(aSize)) {
+     gfxCriticalError(LoggerOptionsBasedOnSize(aSize)) << "Failed to allocate a surface due to invalid size " << aSize;
+     return nullptr;
+   }
+@@ -881,14 +929,13 @@ Factory::SetGlobalEventRecorder(DrawEventRecorder *aRecorder)
+   mRecorder = aRecorder;
+ }
+ 
+-LogForwarder* Factory::mLogForwarder = nullptr;
+-
+ // static
+ void
+ Factory::SetLogForwarder(LogForwarder* aLogFwd) {
+-  mLogForwarder = aLogFwd;
++  sConfig->mLogForwarder = aLogFwd;
+ }
+ 
++
+ // static
+ void
+ CriticalLogger::OutputMessage(const std::string &aString,
+diff --git a/gfx/layers/ImageDataSerializer.cpp b/gfx/layers/ImageDataSerializer.cpp
+index 5dd6aca..331dd04 100644
+--- a/gfx/layers/ImageDataSerializer.cpp
++++ b/gfx/layers/ImageDataSerializer.cpp
+@@ -84,21 +84,23 @@ ImageDataSerializerBase::ComputeMinBufferSize(IntSize aSize,
+                                               SurfaceFormat aFormat)
+ {
+   MOZ_ASSERT(aSize.height >= 0 && aSize.width >= 0);
+-  if (aSize.height <= 0 || aSize.width <= 0) {
+-    gfxDebug() << "Non-positive image buffer size request " << aSize.width << "x" << aSize.height;
++
++  // This takes care of checking whether there could be overflow
++  // with enough margin for the metadata.
++  if (!gfx::Factory::AllowedSurfaceSize(aSize)) {
+     return 0;
+   }
+ 
+-  CheckedInt<int32_t> bufsize = ComputeStride(aFormat, aSize.width);
+-  bufsize *= aSize.height;
++  int32_t bufsize = GetAlignedStride<16>(ComputeStride(aFormat, aSize.width)
++                                         * aSize.height)
++                  + SurfaceBufferInfo::GetOffset();
+ 
+-  if (!bufsize.isValid() || bufsize.value() <= 0) {
+-    gfxDebug() << "Buffer size overflow " << aSize.width << "x" << aSize.height;
++  if (bufsize < 0) {
++    // This should not be possible thanks to Factory::AllowedSurfaceSize
+     return 0;
+   }
+ 
+-  return SurfaceBufferInfo::GetOffset()
+-       + GetAlignedStride<16>(bufsize.value());
++  return bufsize;
+ }
+ 
+ void
+@@ -114,7 +116,8 @@ ImageDataSerializerBase::Validate()
+   }
+   size_t requiredSize =
+            ComputeMinBufferSize(IntSize(info->width, info->height), info->format);
+-  mIsValid = requiredSize <= mDataSize;
++
++  mIsValid = !!requiredSize && requiredSize <= mDataSize;
+ }
+ 
+ uint8_t*
+diff --git a/gfx/layers/YCbCrImageDataSerializer.cpp b/gfx/layers/YCbCrImageDataSerializer.cpp
+index c8e148d..05f5ab2 100644
+--- a/gfx/layers/YCbCrImageDataSerializer.cpp
++++ b/gfx/layers/YCbCrImageDataSerializer.cpp
+@@ -150,6 +150,13 @@ YCbCrImageDataDeserializerBase::ComputeMinBufferSize(const gfx::IntSize& aYSize,
+     gfxDebug() << "Non-positive YCbCr buffer size request " << aYSize.height << "x" << aYSize.width << ", " << aCbCrSize.height << "x" << aCbCrSize.width;
+     return 0;
+   }
++
++  if (!gfx::Factory::AllowedSurfaceSize(aYSize) ||
++      aCbCrSize.width > aYSize.width ||
++      aCbCrSize.height > aYSize.height) {
++    return 0;
++  }
++
+   return ComputeOffset(aYSize.height, aYStride)
+          + 2 * ComputeOffset(aCbCrSize.height, aCbCrStride)
+          + MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo));
+diff --git a/gfx/layers/client/TextureClient.cpp b/gfx/layers/client/TextureClient.cpp
+index 9b45ca0..6ae7cbf 100644
+--- a/gfx/layers/client/TextureClient.cpp
++++ b/gfx/layers/client/TextureClient.cpp
+@@ -315,6 +315,10 @@ TextureClient::CreateForDrawing(ISurfaceAllocator* aAllocator,
+     aMoz2DBackend = gfxPlatform::GetPlatform()->GetContentBackend();
+   }
+ 
++  if (!gfx::Factory::AllowedSurfaceSize(aSize)) {
++    return nullptr;
++  }
++
+   RefPtr<TextureClient> texture;
+ 
+ #if defined(MOZ_WIDGET_GONK) || defined(XP_WIN)
+@@ -415,6 +419,10 @@ TextureClient::CreateForRawBufferAccess(ISurfaceAllocator* aAllocator,
+                                         TextureFlags aTextureFlags,
+                                         TextureAllocationFlags aAllocFlags)
+ {
++  if (!gfx::Factory::AllowedSurfaceSize(aSize)) {
++    return nullptr;
++  }
++
+   RefPtr<BufferTextureClient> texture =
+     CreateBufferTextureClient(aAllocator, aFormat,
+                               aTextureFlags, aMoz2DBackend);
+@@ -434,6 +442,10 @@ TextureClient::CreateForYCbCr(ISurfaceAllocator* aAllocator,
+                               StereoMode aStereoMode,
+                               TextureFlags aTextureFlags)
+ {
++  if (!gfx::Factory::AllowedSurfaceSize(aYSize)) {
++    return nullptr;
++  }
++
+   RefPtr<BufferTextureClient> texture;
+   if (aAllocator->IsSameProcess()) {
+     texture = new MemoryTextureClient(aAllocator, gfx::SurfaceFormat::YUV,
+diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp
+index 41e4b0c..209a0a8 100644
+--- a/gfx/thebes/gfxPlatform.cpp
++++ b/gfx/thebes/gfxPlatform.cpp
+@@ -458,13 +458,18 @@ gfxPlatform::Init()
+     }
+     gEverInitialized = true;
+ 
+-    CrashStatsLogForwarder* logForwarder = new CrashStatsLogForwarder("GraphicsCriticalError");
+-    mozilla::gfx::Factory::SetLogForwarder(logForwarder);
+-
+     // Initialize the preferences by creating the singleton.
+     gfxPrefs::GetSingleton();
+ 
+-    logForwarder->SetCircularBufferSize(gfxPrefs::GfxLoggingCrashLength());
++    auto fwd = new CrashStatsLogForwarder("GraphicsCriticalError");
++    fwd->SetCircularBufferSize(gfxPrefs::GfxLoggingCrashLength());
++
++    mozilla::gfx::Config cfg;
++    cfg.mLogForwarder = fwd;
++    cfg.mMaxTextureSize = gfxPrefs::MaxTextureSize();
++    cfg.mMaxAllocSize = gfxPrefs::MaxAllocSize();
++
++    gfx::Factory::Init(cfg);
+ 
+     gGfxPlatformPrefsLock = new Mutex("gfxPlatform::gGfxPlatformPrefsLock");
+ 
+@@ -641,6 +646,8 @@ gfxPlatform::Shutdown()
+     delete mozilla::gfx::Factory::GetLogForwarder();
+     mozilla::gfx::Factory::SetLogForwarder(nullptr);
+ 
++    gfx::Factory::ShutDown();
++
+     delete gGfxPlatformPrefsLock;
+ 
+     gfxPrefs::DestroySingleton();
+diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h
+index b7a5fb9..038e1ff 100644
+--- a/gfx/thebes/gfxPrefs.h
++++ b/gfx/thebes/gfxPrefs.h
+@@ -209,6 +209,9 @@ private:
+   DECL_GFX_PREF(Live, "gfx.layerscope.port",                   LayerScopePort, int32_t, 23456);
+   // Note that        "gfx.logging.level" is defined in Logging.h
+   DECL_GFX_PREF(Once, "gfx.logging.crash.length",              GfxLoggingCrashLength, uint32_t, 6);
++  // The maximums here are quite conservative, we can tighten them if problems show up.
++  DECL_GFX_PREF(Once, "gfx.max-alloc-size",                    MaxAllocSize, int32_t, (int32_t)500000000);
++  DECL_GFX_PREF(Once, "gfx.max-texture-size",                  MaxTextureSize, int32_t, (int32_t)32767);
+   DECL_GFX_PREF(Live, "gfx.perf-warnings.enabled",             PerfWarnings, bool, false);
+   DECL_GFX_PREF(Once, "gfx.work-around-driver-bugs",           WorkAroundDriverBugs, bool, true);
+ 
+-- 
+2.6.3
+
diff --git a/gnu/packages/patches/icecat-CVE-2015-7213-pt1.patch b/gnu/packages/patches/icecat-CVE-2015-7213-pt1.patch
new file mode 100644
index 0000000000..854c91b8aa
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2015-7213-pt1.patch
@@ -0,0 +1,32 @@
+From 3f31bf9e243fb3de26e36d6be0bb0153f51c5b2a Mon Sep 17 00:00:00 2001
+From: Jean-Yves Avenard <jyavenard@mozilla.com>
+Date: Wed, 9 Dec 2015 09:54:58 +0100
+Subject: [PATCH] Bug 1206211 - P1. Ensure operation can't overflow.
+ r=kentuckyfriedtakahe, a=sylvestre
+
+---
+ .../frameworks/av/media/libstagefright/MPEG4Extractor.cpp            | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
+index 22163fa..318152a 100644
+--- a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
++++ b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
+@@ -508,10 +508,13 @@ status_t MPEG4Extractor::readMetaData() {
+     CHECK_NE(err, (status_t)NO_INIT);
+ 
+     // copy pssh data into file metadata
+-    int psshsize = 0;
++    uint64_t psshsize = 0;
+     for (size_t i = 0; i < mPssh.size(); i++) {
+         psshsize += 20 + mPssh[i].datalen;
+     }
++    if (psshsize > kMAX_ALLOCATION) {
++        return ERROR_MALFORMED;
++    }
+     if (psshsize) {
+         char *buf = (char*)malloc(psshsize);
+         char *ptr = buf;
+-- 
+2.6.3
+
diff --git a/gnu/packages/patches/icecat-CVE-2015-7213-pt2.patch b/gnu/packages/patches/icecat-CVE-2015-7213-pt2.patch
new file mode 100644
index 0000000000..20bbd36281
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2015-7213-pt2.patch
@@ -0,0 +1,27 @@
+From bb6870bd6dc3acb183f44360c7cc6488656f47ea Mon Sep 17 00:00:00 2001
+From: Jean-Yves Avenard <jyavenard@mozilla.com>
+Date: Wed, 9 Dec 2015 09:55:16 +0100
+Subject: [PATCH] Bug 1206211 - P2. Abort on OOM. r=kentuckyfriedtakahe,
+ a=sylvestre
+
+---
+ .../frameworks/av/media/libstagefright/MPEG4Extractor.cpp              | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
+index 318152a..c6aaf1d 100644
+--- a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
++++ b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
+@@ -517,6 +517,9 @@ status_t MPEG4Extractor::readMetaData() {
+     }
+     if (psshsize) {
+         char *buf = (char*)malloc(psshsize);
++        if (!buf) {
++            return ERROR_MALFORMED;
++        }
+         char *ptr = buf;
+         for (size_t i = 0; i < mPssh.size(); i++) {
+             memcpy(ptr, mPssh[i].uuid, 20); // uuid + length
+-- 
+2.6.3
+
diff --git a/gnu/packages/patches/icecat-CVE-2015-7214.patch b/gnu/packages/patches/icecat-CVE-2015-7214.patch
new file mode 100644
index 0000000000..3a56d3d2cd
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2015-7214.patch
@@ -0,0 +1,47 @@
+From 487799700b0b676c2c6b95ad33c8afb8dbd329d8 Mon Sep 17 00:00:00 2001
+From: Bobby Holley <bobbyholley@gmail.com>
+Date: Mon, 14 Dec 2015 15:36:20 -0500
+Subject: [PATCH] Bug 1228950 - Disallow scheme sets on nsHostObjectURI. r=bz,
+ a=lizzard
+
+---
+ dom/base/nsHostObjectURI.cpp | 9 +++++++++
+ dom/base/nsHostObjectURI.h   | 2 ++
+ 2 files changed, 11 insertions(+)
+
+diff --git a/dom/base/nsHostObjectURI.cpp b/dom/base/nsHostObjectURI.cpp
+index 94b02ff..57b0209 100644
+--- a/dom/base/nsHostObjectURI.cpp
++++ b/dom/base/nsHostObjectURI.cpp
+@@ -81,6 +81,15 @@ nsHostObjectURI::Write(nsIObjectOutputStream* aStream)
+                                         true);
+ }
+ 
++NS_IMETHODIMP
++nsHostObjectURI::SetScheme(const nsACString& aScheme)
++{
++  // Disallow setting the scheme, since that could cause us to be associated
++  // with a different protocol handler that doesn't expect us to be carrying
++  // around a principal with nsIURIWithPrincipal.
++  return NS_ERROR_FAILURE;
++}
++
+ // nsIURI methods:
+ nsresult
+ nsHostObjectURI::CloneInternal(nsSimpleURI::RefHandlingEnum aRefHandlingMode,
+diff --git a/dom/base/nsHostObjectURI.h b/dom/base/nsHostObjectURI.h
+index b468d5d..23ff7ab 100644
+--- a/dom/base/nsHostObjectURI.h
++++ b/dom/base/nsHostObjectURI.h
+@@ -34,6 +34,8 @@ public:
+   NS_DECL_NSISERIALIZABLE
+   NS_DECL_NSICLASSINFO
+ 
++  NS_IMETHOD SetScheme(const nsACString &aProtocol) override;
++
+   // Override CloneInternal() and EqualsInternal()
+   virtual nsresult CloneInternal(RefHandlingEnum aRefHandlingMode,
+                                  nsIURI** aClone) override;
+-- 
+2.6.3
+
diff --git a/gnu/packages/patches/icecat-CVE-2015-7222-pt1.patch b/gnu/packages/patches/icecat-CVE-2015-7222-pt1.patch
new file mode 100644
index 0000000000..c5d0e4ad60
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2015-7222-pt1.patch
@@ -0,0 +1,112 @@
+From 76e6db3e514350fd146cb04425e669d63b59f889 Mon Sep 17 00:00:00 2001
+From: Gerald Squelart <gsquelart@mozilla.com>
+Date: Wed, 9 Dec 2015 09:59:37 +0100
+Subject: [PATCH] Bug 1216748 - p2. Handle failed malloc in Metadata storage -
+ r=rillian, a=sylvestre
+
+---
+ .../av/include/media/stagefright/MetaData.h        |  2 +-
+ .../av/media/libstagefright/MetaData.cpp           | 35 ++++++++++++++--------
+ 2 files changed, 24 insertions(+), 13 deletions(-)
+
+diff --git a/media/libstagefright/frameworks/av/include/media/stagefright/MetaData.h b/media/libstagefright/frameworks/av/include/media/stagefright/MetaData.h
+index 30d969d..0a8ff77 100644
+--- a/media/libstagefright/frameworks/av/include/media/stagefright/MetaData.h
++++ b/media/libstagefright/frameworks/av/include/media/stagefright/MetaData.h
+@@ -248,7 +248,7 @@ private:
+             return mSize <= sizeof(u.reservoir);
+         }
+ 
+-        void allocateStorage(size_t size);
++        bool allocateStorage(size_t size);
+         void freeStorage();
+ 
+         void *storage() {
+diff --git a/media/libstagefright/frameworks/av/media/libstagefright/MetaData.cpp b/media/libstagefright/frameworks/av/media/libstagefright/MetaData.cpp
+index c832c96..cba324d 100644
+--- a/media/libstagefright/frameworks/av/media/libstagefright/MetaData.cpp
++++ b/media/libstagefright/frameworks/av/media/libstagefright/MetaData.cpp
+@@ -220,7 +220,7 @@ bool MetaData::findData(uint32_t key, uint32_t *type,
+ }
+ 
+ MetaData::typed_data::typed_data()
+-    : mType(0),
++    : mType(TYPE_NONE),
+       mSize(0) {
+ }
+ 
+@@ -231,17 +231,19 @@ MetaData::typed_data::~typed_data() {
+ MetaData::typed_data::typed_data(const typed_data &from)
+     : mType(from.mType),
+       mSize(0) {
+-    allocateStorage(from.mSize);
+-    memcpy(storage(), from.storage(), mSize);
++    if (allocateStorage(from.mSize)) {
++        memcpy(storage(), from.storage(), mSize);
++    }
+ }
+ 
+ MetaData::typed_data &MetaData::typed_data::operator=(
+         const MetaData::typed_data &from) {
+     if (this != &from) {
+         clear();
+-        mType = from.mType;
+-        allocateStorage(from.mSize);
+-        memcpy(storage(), from.storage(), mSize);
++        if (allocateStorage(from.mSize)) {
++            mType = from.mType;
++            memcpy(storage(), from.storage(), mSize);
++        }
+     }
+ 
+     return *this;
+@@ -250,16 +252,17 @@ MetaData::typed_data &MetaData::typed_data::operator=(
+ void MetaData::typed_data::clear() {
+     freeStorage();
+ 
+-    mType = 0;
++    mType = TYPE_NONE;
+ }
+ 
+ void MetaData::typed_data::setData(
+         uint32_t type, const void *data, size_t size) {
+     clear();
+ 
+-    mType = type;
+-    allocateStorage(size);
+-    memcpy(storage(), data, size);
++    if (allocateStorage(size)) {
++        mType = type;
++        memcpy(storage(), data, size);
++    }
+ }
+ 
+ void MetaData::typed_data::getData(
+@@ -269,14 +272,22 @@ void MetaData::typed_data::getData(
+     *data = storage();
+ }
+ 
+-void MetaData::typed_data::allocateStorage(size_t size) {
++bool MetaData::typed_data::allocateStorage(size_t size) {
++    // Update mSize now, as it is needed by usesReservoir() below.
++    // (mSize will be reset if the allocation fails further below.)
+     mSize = size;
+ 
+     if (usesReservoir()) {
+-        return;
++        return true;
+     }
+ 
+     u.ext_data = malloc(mSize);
++    if (!u.ext_data) {
++      mType = TYPE_NONE;
++      mSize = 0;
++      return false;
++    }
++    return true;
+ }
+ 
+ void MetaData::typed_data::freeStorage() {
+-- 
+2.6.3
+
diff --git a/gnu/packages/patches/icecat-CVE-2015-7222-pt2.patch b/gnu/packages/patches/icecat-CVE-2015-7222-pt2.patch
new file mode 100644
index 0000000000..688d7f903f
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2015-7222-pt2.patch
@@ -0,0 +1,34 @@
+From 63c353cf8ec6b787936f602532026bd9923a16e4 Mon Sep 17 00:00:00 2001
+From: Gerald Squelart <gsquelart@mozilla.com>
+Date: Wed, 9 Dec 2015 10:00:13 +0100
+Subject: [PATCH] Bug 1216748 - p3. Ensure 'covr' data size cannot create
+ underflow - r=rillian, a=sylvestre
+
+---
+ .../frameworks/av/media/libstagefright/MPEG4Extractor.cpp            | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
+index c6aaf1d..a69fc14 100644
+--- a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
++++ b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
+@@ -1889,12 +1889,15 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
+             if (mFileMetaData != NULL) {
+                 ALOGV("chunk_data_size = %lld and data_offset = %lld",
+                         chunk_data_size, data_offset);
++                const int kSkipBytesOfDataBox = 16;
++                if (chunk_data_size <= kSkipBytesOfDataBox) {
++                  return ERROR_MALFORMED;
++                }
+                 sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1);
+                 if (mDataSource->readAt(
+                     data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) {
+                     return ERROR_IO;
+                 }
+-                const int kSkipBytesOfDataBox = 16;
+                 mFileMetaData->setData(
+                     kKeyAlbumArt, MetaData::TYPE_NONE,
+                     buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox);
+-- 
+2.6.3
+
diff --git a/gnu/packages/patches/icecat-CVE-2015-7222-pt3.patch b/gnu/packages/patches/icecat-CVE-2015-7222-pt3.patch
new file mode 100644
index 0000000000..2f3c95623d
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2015-7222-pt3.patch
@@ -0,0 +1,37 @@
+From 0221ef0c389bff196ff59fa18232467d3648b926 Mon Sep 17 00:00:00 2001
+From: Gerald Squelart <gsquelart@mozilla.com>
+Date: Wed, 9 Dec 2015 10:00:32 +0100
+Subject: [PATCH] Bug 1216748 - p4. Check other Metadata::setData uses -
+ r=rillian, a=sylvestre
+
+Found only one other use that needed better checks: the size of the pssh
+data was only checked after all items were added up; so it would be
+possible to create a set of big items such that they create an overflow,
+but the final sum looks reasonable.
+Instead each item size should be checked, and the sum should also be
+checked at each step.
+---
+ .../frameworks/av/media/libstagefright/MPEG4Extractor.cpp          | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
+index a69fc14..413a495 100644
+--- a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
++++ b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
+@@ -511,9 +511,10 @@ status_t MPEG4Extractor::readMetaData() {
+     uint64_t psshsize = 0;
+     for (size_t i = 0; i < mPssh.size(); i++) {
+         psshsize += 20 + mPssh[i].datalen;
+-    }
+-    if (psshsize > kMAX_ALLOCATION) {
+-        return ERROR_MALFORMED;
++        if (mPssh[i].datalen > kMAX_ALLOCATION - 20 ||
++            psshsize > kMAX_ALLOCATION) {
++            return ERROR_MALFORMED;
++        }
+     }
+     if (psshsize) {
+         char *buf = (char*)malloc(psshsize);
+-- 
+2.6.3
+