!1 fix CVE-2020-28491
From: @zhanghua1831 Reviewed-by: @maminjie,@wangchong1995924 Signed-off-by: @wangchong1995924
This commit is contained in:
commit
b7b8ef11e4
230
CVE-2020-28491.patch
Normal file
230
CVE-2020-28491.patch
Normal 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
|
||||||
|
|
||||||
@ -1,10 +1,11 @@
|
|||||||
Name: jackson-dataformats-binary
|
Name: jackson-dataformats-binary
|
||||||
Version: 2.9.4
|
Version: 2.9.4
|
||||||
Release: 5
|
Release: 6
|
||||||
Summary: A multi-module umbrella project for Jackson standard binary data format backends
|
Summary: A multi-module umbrella project for Jackson standard binary data format backends
|
||||||
License: ASL 2.0 and BSD
|
License: ASL 2.0 and BSD
|
||||||
URL: https://github.com/FasterXML/jackson-dataformats-binary
|
URL: https://github.com/FasterXML/jackson-dataformats-binary
|
||||||
Source0: https://github.com/FasterXML/jackson-dataformats-binary/archive/%{name}-%{version}.tar.gz
|
Source0: https://github.com/FasterXML/jackson-dataformats-binary/archive/%{name}-%{version}.tar.gz
|
||||||
|
Patch0000: CVE-2020-28491.patch
|
||||||
BuildArch: noarch
|
BuildArch: noarch
|
||||||
|
|
||||||
BuildRequires: maven-local, mvn(com.fasterxml.jackson.core:jackson-annotations) >= %{version}, mvn(com.fasterxml.jackson.core:jackson-core) >= %{version}
|
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*
|
/usr/share/maven*
|
||||||
|
|
||||||
%changelog
|
%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
|
* Sat Dec 7 2019 openEuler Buildteam <buildteam@openeuler.org> - 2.9.4-5
|
||||||
- Package init
|
- Package init
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user