[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#934518: stretch-pu: package libebml/1.3.4-1



Package: release.debian.org
Severity: normal
Tags: stretch
User: release.debian.org@packages.debian.org
Usertags: pu

Hi,

I'd like to fix CVE-2019-13615 in libebml in stetch (the security team
classified it as no-DSA). The proposed debdiff is attached.

Cheers
-- 
Sebastian Ramacher
diff --git a/debian/changelog b/debian/changelog
index 5982b33..b32cf11 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+libebml (1.3.4-1+deb9u1) stretch; urgency=medium
+
+  * debian/patches: Apply upstream fixes for heap-based buffer over-reads.
+    (CVE-2019-13615) (Closes: #932241)
+
+ -- Sebastian Ramacher <sramacher@debian.org>  Sun, 11 Aug 2019 22:09:57 +0200
+
 libebml (1.3.4-1) unstable; urgency=medium
 
   * New upstream release
diff --git a/debian/gbp.conf b/debian/gbp.conf
index 682c4cf..3e5b7c4 100644
--- a/debian/gbp.conf
+++ b/debian/gbp.conf
@@ -1,6 +1,6 @@
 [DEFAULT]
 upstream-branch = upstream
-debian-branch = master
+debian-branch = stretch
 upstream-tag = upstream/%(version)s
 debian-tag = debian/%(version)s
 pristine-tar = True
diff --git a/debian/patches/0001-Check-the-max-size-to-read-before-actually-reading.patch b/debian/patches/0001-Check-the-max-size-to-read-before-actually-reading.patch
new file mode 100644
index 0000000..e2bbf3c
--- /dev/null
+++ b/debian/patches/0001-Check-the-max-size-to-read-before-actually-reading.patch
@@ -0,0 +1,40 @@
+From: Steve Lhomme <slhomme@matroska.org>
+Date: Mon, 27 Nov 2017 09:48:32 +0100
+Subject: Check the max size to read before actually reading
+
+The size check waas also missing from the length parsing
+---
+ src/EbmlElement.cpp | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/src/EbmlElement.cpp b/src/EbmlElement.cpp
+index d25abe8..b92522e 100644
+--- a/src/EbmlElement.cpp
++++ b/src/EbmlElement.cpp
+@@ -398,12 +398,14 @@ EbmlElement * EbmlElement::FindNextElement(IOCallback & DataStream, const EbmlSe
+         memmove(&PossibleIdNSize[0],&PossibleIdNSize[1], --ReadIndex);
+       }
+ 
++      if (MaxDataSize <= ReadSize)
++        break;
+       if (DataStream.read(&PossibleIdNSize[ReadIndex++], 1) == 0) {
+         return NULL; // no more data ?
+       }
+       ReadSize++;
+ 
+-    } while (!bFound && MaxDataSize > ReadSize);
++    } while (!bFound);
+ 
+     SizeIdx = ReadIndex;
+     ReadIndex -= PossibleID_Length;
+@@ -422,6 +424,10 @@ EbmlElement * EbmlElement::FindNextElement(IOCallback & DataStream, const EbmlSe
+         bFound = false;
+         break;
+       }
++      if (MaxDataSize <= ReadSize) {
++        bFound = false;
++        break;
++      }
+       if( DataStream.read( &PossibleIdNSize[SizeIdx++], 1 ) == 0 ) {
+         return NULL; // no more data ?
+       }
diff --git a/debian/patches/0002-Do-not-output-an-element-with-size-Unknown-if-it-s-n.patch b/debian/patches/0002-Do-not-output-an-element-with-size-Unknown-if-it-s-n.patch
new file mode 100644
index 0000000..a7c08e4
--- /dev/null
+++ b/debian/patches/0002-Do-not-output-an-element-with-size-Unknown-if-it-s-n.patch
@@ -0,0 +1,38 @@
+From: Steve Lhomme <slhomme@matroska.org>
+Date: Wed, 6 Dec 2017 09:32:13 +0100
+Subject: Do not output an element with size Unknown if it's not allowed
+
+Similar to what is done in FindNextID().
+
+SetSizeInfinite() doesn't actually set anything. SetSizeIsFinite() is the one
+that actually sets it and it is an internal API.
+---
+ src/EbmlElement.cpp | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/src/EbmlElement.cpp b/src/EbmlElement.cpp
+index b92522e..26510c7 100644
+--- a/src/EbmlElement.cpp
++++ b/src/EbmlElement.cpp
+@@ -451,15 +451,13 @@ EbmlElement * EbmlElement::FindNextElement(IOCallback & DataStream, const EbmlSe
+           //  1 : same level
+           //  + : further parent
+           if (Result->ValidateSize() && (SizeFound == SizeUnknown || UpperLevel > 0 || MaxDataSize == 0 || MaxDataSize >= (PossibleID_Length + PossibleSizeLength + SizeFound))) {
+-            if (SizeFound == SizeUnknown) {
+-              Result->SetSizeInfinite();
++            if (SizeFound != SizeUnknown || Result->SetSizeInfinite()) {
++              Result->SizePosition = DataStream.getFilePointer() - SizeIdx + EBML_ID_LENGTH(PossibleID);
++              Result->ElementPosition = Result->SizePosition - EBML_ID_LENGTH(PossibleID);
++              // place the file at the beggining of the data
++              DataStream.setFilePointer(Result->SizePosition + _SizeLength);
++              return Result;
+             }
+-
+-            Result->SizePosition = DataStream.getFilePointer() - SizeIdx + EBML_ID_LENGTH(PossibleID);
+-            Result->ElementPosition = Result->SizePosition - EBML_ID_LENGTH(PossibleID);
+-            // place the file at the beggining of the data
+-            DataStream.setFilePointer(Result->SizePosition + _SizeLength);
+-            return Result;
+           }
+         }
+         delete Result;
diff --git a/debian/patches/0003-Exit-the-max-size-loop-when-there-s-nothing-left-pos.patch b/debian/patches/0003-Exit-the-max-size-loop-when-there-s-nothing-left-pos.patch
new file mode 100644
index 0000000..fb27d0b
--- /dev/null
+++ b/debian/patches/0003-Exit-the-max-size-loop-when-there-s-nothing-left-pos.patch
@@ -0,0 +1,23 @@
+From: Steve Lhomme <slhomme@matroska.org>
+Date: Mon, 22 Jan 2018 15:42:53 +0100
+Subject: Exit the max size loop when there's nothing left possible to find
+
+DataStream.getFilePointer() is not correct in this context. It might force to
+exit too early.
+---
+ src/EbmlElement.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/EbmlElement.cpp b/src/EbmlElement.cpp
+index 26510c7..1e35f29 100644
+--- a/src/EbmlElement.cpp
++++ b/src/EbmlElement.cpp
+@@ -468,7 +468,7 @@ EbmlElement * EbmlElement::FindNextElement(IOCallback & DataStream, const EbmlSe
+     ReadIndex = SizeIdx - 1;
+     memmove(&PossibleIdNSize[0], &PossibleIdNSize[1], ReadIndex);
+     UpperLevel = UpperLevel_original;
+-  } while ( MaxDataSize > DataStream.getFilePointer() - SizeIdx + PossibleID_Length );
++  } while ( MaxDataSize >= ReadSize );
+ 
+   return NULL;
+ }
diff --git a/debian/patches/0004-Rework-the-way-we-look-at-the-end-boundary-when-look.patch b/debian/patches/0004-Rework-the-way-we-look-at-the-end-boundary-when-look.patch
new file mode 100644
index 0000000..b7a2f30
--- /dev/null
+++ b/debian/patches/0004-Rework-the-way-we-look-at-the-end-boundary-when-look.patch
@@ -0,0 +1,65 @@
+From: Steve Lhomme <slhomme@matroska.org>
+Date: Tue, 23 Jan 2018 15:28:09 +0100
+Subject: Rework the way we look at the end boundary when looking an element
+ in a parent
+
+The test `MaxDataSize >= (PossibleID_Length + PossibleSizeLength + SizeFound)`
+is incorrect when there was garbage data skipped inside the PossibleIdNLength
+table.
+
+Now we keep track of how many memmove we had to do to know the real position of
+the PossibleIdNLength data since we started reading. That allows a proper check
+on the end value since that start.
+---
+ src/EbmlElement.cpp | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/src/EbmlElement.cpp b/src/EbmlElement.cpp
+index 1e35f29..fba29fa 100644
+--- a/src/EbmlElement.cpp
++++ b/src/EbmlElement.cpp
+@@ -366,11 +366,12 @@ EbmlElement * EbmlElement::FindNextElement(IOCallback & DataStream, const EbmlSe
+   int PossibleSizeLength;
+   uint64 SizeUnknown;
+   int ReadIndex = 0; // trick for the algo, start index at 0
+-  uint32 ReadSize = 0;
++  uint32 ReadSize = 0, IdStart = 0;
+   uint64 SizeFound;
+   int SizeIdx;
+   bool bFound;
+   int UpperLevel_original = UpperLevel;
++  uint64 ParseStart = DataStream.getFilePointer();
+ 
+   do {
+     // read a potential ID
+@@ -396,6 +397,7 @@ EbmlElement * EbmlElement::FindNextElement(IOCallback & DataStream, const EbmlSe
+         // ID not found
+         // shift left the read octets
+         memmove(&PossibleIdNSize[0],&PossibleIdNSize[1], --ReadIndex);
++        IdStart++;
+       }
+ 
+       if (MaxDataSize <= ReadSize)
+@@ -450,10 +452,11 @@ EbmlElement * EbmlElement::FindNextElement(IOCallback & DataStream, const EbmlSe
+           //  0 : child
+           //  1 : same level
+           //  + : further parent
+-          if (Result->ValidateSize() && (SizeFound == SizeUnknown || UpperLevel > 0 || MaxDataSize == 0 || MaxDataSize >= (PossibleID_Length + PossibleSizeLength + SizeFound))) {
++          if (Result->ValidateSize() && (SizeFound == SizeUnknown || UpperLevel > 0 || MaxDataSize == 0 ||
++                                         MaxDataSize >= (IdStart + PossibleID_Length + _SizeLength + SizeFound))) {
+             if (SizeFound != SizeUnknown || Result->SetSizeInfinite()) {
+-              Result->SizePosition = DataStream.getFilePointer() - SizeIdx + EBML_ID_LENGTH(PossibleID);
+-              Result->ElementPosition = Result->SizePosition - EBML_ID_LENGTH(PossibleID);
++              Result->ElementPosition = ParseStart + IdStart;
++              Result->SizePosition = Result->ElementPosition + PossibleID_Length;
+               // place the file at the beggining of the data
+               DataStream.setFilePointer(Result->SizePosition + _SizeLength);
+               return Result;
+@@ -467,6 +470,7 @@ EbmlElement * EbmlElement::FindNextElement(IOCallback & DataStream, const EbmlSe
+     // recover all the data in the buffer minus one byte
+     ReadIndex = SizeIdx - 1;
+     memmove(&PossibleIdNSize[0], &PossibleIdNSize[1], ReadIndex);
++    IdStart++;
+     UpperLevel = UpperLevel_original;
+   } while ( MaxDataSize >= ReadSize );
+ 
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..8041e2b
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,4 @@
+0001-Check-the-max-size-to-read-before-actually-reading.patch
+0002-Do-not-output-an-element-with-size-Unknown-if-it-s-n.patch
+0003-Exit-the-max-size-loop-when-there-s-nothing-left-pos.patch
+0004-Rework-the-way-we-look-at-the-end-boundary-when-look.patch

Attachment: signature.asc
Description: PGP signature


Reply to: