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