!1 fix CVE-2020-28491

From: @zhanghua1831
Reviewed-by: @maminjie,@wangchong1995924
Signed-off-by: @wangchong1995924
This commit is contained in:
openeuler-ci-bot 2021-03-03 09:28:13 +08:00 committed by Gitee
commit b7b8ef11e4
2 changed files with 235 additions and 1 deletions

230
CVE-2020-28491.patch Normal file
View File

@ -0,0 +1,230 @@
From de072d314af8f5f269c8abec6930652af67bc8e6 Mon Sep 17 00:00:00 2001
From: Tatu Saloranta <tatu.saloranta@iki.fi>
Date: Fri, 4 Dec 2020 16:27:55 -0800
Subject: [PATCH] Fix eager allocation aspect of #186
---
.../dataformat/cbor/CBORGenerator.java | 2 +-
.../jackson/dataformat/cbor/CBORParser.java | 115 ++++++++++++++----
2 files changed, 90 insertions(+), 27 deletions(-)
diff --git a/cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORGenerator.java b/cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORGenerator.java
index f813f4c..1215c86 100644
--- a/cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORGenerator.java
+++ b/cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORGenerator.java
@@ -190,7 +190,7 @@ public class CBORGenerator extends GeneratorBase
/**
* Number of elements remaining in the current complex structure (if any),
- * when writing defined-length Arrays, Objects; marker {@link #INDEFINITE_LENGTH}
+ * when writing defined-length Arrays, Objects; marker {code INDEFINITE_LENGTH}
* otherwise.
*/
protected int _currentRemainingElements = INDEFINITE_LENGTH;
diff --git a/cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORParser.java b/cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORParser.java
index 2412c7c..ec89f9b 100644
--- a/cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORParser.java
+++ b/cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORParser.java
@@ -63,6 +63,10 @@ public final class CBORParser extends ParserMinimalBase
private final static double MATH_POW_2_10 = Math.pow(2, 10);
private final static double MATH_POW_2_NEG14 = Math.pow(2, -14);
+ // 2.11.4: [dataformats-binary#186] Avoid OOME/DoS for bigger binary;
+ // read only up to 250k
+ protected final static int LONGEST_NON_CHUNKED_BINARY = 250_000;
+
/*
/**********************************************************
/* Configuration
@@ -1500,13 +1504,15 @@ public final class CBORParser extends ParserMinimalBase
}
}
- private int _readAndWriteBytes(OutputStream out, int total) throws IOException
+ private int _readAndWriteBytes(OutputStream out, final int total) throws IOException
{
int left = total;
while (left > 0) {
int avail = _inputEnd - _inputPtr;
if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
+ if (!loadMore()) {
+ _reportIncompleteBinaryRead(total, total-left);
+ }
avail = _inputEnd - _inputPtr;
}
int count = Math.min(avail, left);
@@ -2219,33 +2225,55 @@ public final class CBORParser extends ParserMinimalBase
// either way, got it now
return _inputBuffer[_inputPtr++];
}
-
+
+ /**
+ * Helper called to complete reading of binary data ("byte string") in
+ * case contents are needed.
+ */
@SuppressWarnings("resource")
protected byte[] _finishBytes(int len) throws IOException
{
+ // Chunked?
// First, simple: non-chunked
- if (len >= 0) {
+ if (len <= 0) {
if (len == 0) {
return NO_BYTES;
}
- byte[] b = new byte[len];
- if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
+ return _finishChunkedBytes();
+ }
+ // Non-chunked, contiguous
+ if (len > LONGEST_NON_CHUNKED_BINARY) {
+ // [dataformats-binary#186]: avoid immediate allocation for longest
+ return _finishLongContiguousBytes(len);
+ }
+
+ final byte[] b = new byte[len];
+ final int expLen = len;
+ if (_inputPtr >= _inputEnd) {
+ if (!loadMore()) {
+ _reportIncompleteBinaryRead(expLen, 0);
}
- int ptr = 0;
- while (true) {
- int toAdd = Math.min(len, _inputEnd - _inputPtr);
- System.arraycopy(_inputBuffer, _inputPtr, b, ptr, toAdd);
- _inputPtr += toAdd;
- ptr += toAdd;
- len -= toAdd;
- if (len <= 0) {
- return b;
- }
- loadMoreGuaranteed();
+ }
+
+ int ptr = 0;
+ while (true) {
+ int toAdd = Math.min(len, _inputEnd - _inputPtr);
+ System.arraycopy(_inputBuffer, _inputPtr, b, ptr, toAdd);
+ _inputPtr += toAdd;
+ ptr += toAdd;
+ len -= toAdd;
+ if (len <= 0) {
+ return b;
+ }
+ if (!loadMore()) {
+ _reportIncompleteBinaryRead(expLen, ptr);
}
}
+ }
+ // @since 2.12
+ protected byte[] _finishChunkedBytes() throws IOException
+ {
// or, if not, chunked...
ByteArrayBuilder bb = _getByteArrayBuilder();
while (true) {
@@ -2262,14 +2290,17 @@ public final class CBORParser extends ParserMinimalBase
throw _constructError("Mismatched chunk in chunked content: expected "+CBORConstants.MAJOR_TYPE_BYTES
+" but encountered "+type);
}
- len = _decodeExplicitLength(ch & 0x1F);
+ int len = _decodeExplicitLength(ch & 0x1F);
if (len < 0) {
throw _constructError("Illegal chunked-length indicator within chunked-length value (type "+CBORConstants.MAJOR_TYPE_BYTES+")");
}
+ final int chunkLen = len;
while (len > 0) {
int avail = _inputEnd - _inputPtr;
if (_inputPtr >= _inputEnd) {
- loadMoreGuaranteed();
+ if (!loadMore()) {
+ _reportIncompleteBinaryRead(chunkLen, chunkLen-len);
+ }
avail = _inputEnd - _inputPtr;
}
int count = Math.min(avail, len);
@@ -2280,7 +2311,33 @@ public final class CBORParser extends ParserMinimalBase
}
return bb.toByteArray();
}
-
+
+ // @since 2.12
+ protected byte[] _finishLongContiguousBytes(final int expLen) throws IOException
+ {
+ int left = expLen;
+
+ // 04-Dec-2020, tatu: Let's NOT use recycled instance since we have much
+ // longer content and there is likely less benefit of trying to recycle
+ // segments
+ try (final ByteArrayBuilder bb = new ByteArrayBuilder(LONGEST_NON_CHUNKED_BINARY >> 1)) {
+ while (left > 0) {
+ int avail = _inputEnd - _inputPtr;
+ if (avail <= 0) {
+ if (!loadMore()) {
+ _reportIncompleteBinaryRead(expLen, expLen-left);
+ }
+ avail = _inputEnd - _inputPtr;
+ }
+ int count = Math.min(avail, left);
+ bb.write(_inputBuffer, _inputPtr, count);
+ _inputPtr += count;
+ left -= count;
+ }
+ return bb.toByteArray();
+ }
+ }
+
protected final JsonToken _decodeFieldName() throws IOException
{
if (_inputPtr >= _inputEnd) {
@@ -2429,9 +2486,8 @@ public final class CBORParser extends ParserMinimalBase
} else if (type == CBORConstants.MAJOR_TYPE_INT_NEG) {
name = _numberToName(ch, true);
} else if (type == CBORConstants.MAJOR_TYPE_BYTES) {
- /* 08-Sep-2014, tatu: As per [Issue#5], there are codecs
- * (f.ex. Perl module "CBOR::XS") that use Binary data...
- */
+ // 08-Sep-2014, tatu: As per [Issue#5], there are codecs
+ // (f.ex. Perl module "CBOR::XS") that use Binary data...
final int blen = _decodeExplicitLength(ch & 0x1F);
byte[] b = _finishBytes(blen);
// TODO: Optimize, if this becomes commonly used & bottleneck; we have
@@ -2984,7 +3040,7 @@ public final class CBORParser extends ParserMinimalBase
/**********************************************************
*/
- protected final boolean loadMore() throws IOException
+ protected boolean loadMore() throws IOException
{
if (_inputStream != null) {
_currInputProcessed += _inputEnd;
@@ -3005,7 +3061,7 @@ public final class CBORParser extends ParserMinimalBase
return false;
}
- protected final void loadMoreGuaranteed() throws IOException {
+ protected void loadMoreGuaranteed() throws IOException {
if (!loadMore()) { _reportInvalidEOF(); }
}
@@ -3129,6 +3185,13 @@ public final class CBORParser extends ParserMinimalBase
_reportInvalidOther(mask);
}
+ // @since 2.12
+ protected void _reportIncompleteBinaryRead(int expLen, int actLen) throws IOException
+ {
+ _reportInvalidEOF(String.format(" for Binary value: expected %d bytes, only found %d",
+ expLen, actLen), _currToken);
+ }
+
/*
/**********************************************************
/* Internal methods, other
--
2.23.0

View File

@ -1,10 +1,11 @@
Name: jackson-dataformats-binary
Version: 2.9.4
Release: 5
Release: 6
Summary: A multi-module umbrella project for Jackson standard binary data format backends
License: ASL 2.0 and BSD
URL: https://github.com/FasterXML/jackson-dataformats-binary
Source0: https://github.com/FasterXML/jackson-dataformats-binary/archive/%{name}-%{version}.tar.gz
Patch0000: CVE-2020-28491.patch
BuildArch: noarch
BuildRequires: maven-local, mvn(com.fasterxml.jackson.core:jackson-annotations) >= %{version}, mvn(com.fasterxml.jackson.core:jackson-core) >= %{version}
@ -50,5 +51,8 @@ sed -i 's/\r//' NOTICE LICENSE
/usr/share/maven*
%changelog
* Tue Mar 2 2021 zhanghua <zhanghua40@huawei.com> - 2.9.4-6
- fix CVE-2020-28491
* Sat Dec 7 2019 openEuler Buildteam <buildteam@openeuler.org> - 2.9.4-5
- Package init