diff --git a/SOURCES/0010-quic-Check-we-have-some-data-to-start-decoding-quic-.patch b/SOURCES/0010-quic-Check-we-have-some-data-to-start-decoding-quic-.patch new file mode 100644 index 0000000..85cd780 --- /dev/null +++ b/SOURCES/0010-quic-Check-we-have-some-data-to-start-decoding-quic-.patch @@ -0,0 +1,34 @@ +From d9cc2d4659950df230dfe30e5445b91d4c15604e Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Wed, 29 Apr 2020 15:09:13 +0100 +Subject: [PATCH spice-common 1/4] quic: Check we have some data to start + decoding quic image + +All paths already pass some data to quic_decode_begin but for the +test check it, it's not that expensive test. +Checking for not 0 is enough, all other words will potentially be +read calling more_io_words but we need one to avoid a potential +initial buffer overflow or deferencing an invalid pointer. + +Signed-off-by: Frediano Ziglio +Acked-by: Uri Lublin +--- + common/quic.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/spice-common/common/quic.c b/spice-common/common/quic.c +index 55a5d6c..e03f3af 100644 +--- a/spice-common/common/quic.c ++++ b/spice-common/common/quic.c +@@ -1136,7 +1136,7 @@ int quic_decode_begin(QuicContext *quic, uint32_t *io_ptr, unsigned int num_io_w + int channels; + int bpc; + +- if (!encoder_reset(encoder, io_ptr, io_ptr_end)) { ++ if (!num_io_words || !encoder_reset(encoder, io_ptr, io_ptr_end)) { + return QUIC_ERROR; + } + +-- +2.25.4 + diff --git a/SOURCES/0011-quic-Check-image-size-in-quic_decode_begin.patch b/SOURCES/0011-quic-Check-image-size-in-quic_decode_begin.patch new file mode 100644 index 0000000..8d04a1e --- /dev/null +++ b/SOURCES/0011-quic-Check-image-size-in-quic_decode_begin.patch @@ -0,0 +1,48 @@ +From 19cd6fe85610b424349db2d97e2dd0e2761a4a05 Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Wed, 29 Apr 2020 15:10:24 +0100 +Subject: [PATCH spice-common 2/4] quic: Check image size in quic_decode_begin + +Avoid some overflow in code due to images too big or +negative numbers. + +Signed-off-by: Frediano Ziglio +Acked-by: Uri Lublin +--- + common/quic.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/spice-common/common/quic.c b/spice-common/common/quic.c +index e03f3af..890f128 100644 +--- a/spice-common/common/quic.c ++++ b/spice-common/common/quic.c +@@ -56,6 +56,9 @@ typedef uint8_t BYTE; + #define MINwminext 1 + #define MAXwminext 100000000 + ++/* Maximum image size in pixels, mainly to avoid possible integer overflows */ ++#define SPICE_MAX_IMAGE_SIZE (512 * 1024 * 1024 - 1) ++ + typedef struct QuicFamily { + unsigned int nGRcodewords[MAXNUMCODES]; /* indexed by code number, contains number of + unmodified GR codewords in the code */ +@@ -1165,6 +1168,16 @@ int quic_decode_begin(QuicContext *quic, uint32_t *io_ptr, unsigned int num_io_w + height = encoder->io_word; + decode_eat32bits(encoder); + ++ if (width <= 0 || height <= 0) { ++ encoder->usr->warn(encoder->usr, "invalid size\n"); ++ return QUIC_ERROR; ++ } ++ ++ /* avoid too big images */ ++ if ((uint64_t) width * height > SPICE_MAX_IMAGE_SIZE) { ++ encoder->usr->error(encoder->usr, "image too large\n"); ++ } ++ + quic_image_params(encoder, type, &channels, &bpc); + + if (!encoder_reset_channels(encoder, channels, width, bpc)) { +-- +2.25.4 + diff --git a/SOURCES/0012-quic-Check-RLE-lengths.patch b/SOURCES/0012-quic-Check-RLE-lengths.patch new file mode 100644 index 0000000..b7d95ca --- /dev/null +++ b/SOURCES/0012-quic-Check-RLE-lengths.patch @@ -0,0 +1,52 @@ +From d45a4954d73b41a255b8b4ec57c01ae87ec2936e Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Wed, 29 Apr 2020 15:11:38 +0100 +Subject: [PATCH spice-common 3/4] quic: Check RLE lengths + +Avoid buffer overflows decoding images. On compression we compute +lengths till end of line so it won't cause regressions. +Proved by fuzzing the code. + +Signed-off-by: Frediano Ziglio +Acked-by: Uri Lublin +--- + common/quic_tmpl.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/spice-common/common/quic_rgb_tmpl.c b/spice-common/common/quic_rgb_tmpl.c +index 4800ece..7fdfedf 100644 +--- a/spice-common/common/quic_rgb_tmpl.c ++++ b/spice-common/common/quic_rgb_tmpl.c +@@ -599,7 +599,11 @@ static void FNAME(uncompress_row_seg)(Encoder *encoder, + do_run: + state->waitcnt = stopidx - i; + run_index = i; +- run_end = i + decode_run(encoder); ++ run_end = decode_run(encoder); ++ if (run_end < 0 || run_end > (end - i)) { ++ encoder->usr->error(encoder->usr, "wrong RLE\n"); ++ } ++ run_end += i; + + for (; i < run_end; i++) { + UNCOMPRESS_PIX_START(&cur_row[i]); +diff --git a/spice-common/common/quic_tmpl.c b/spice-common/common/quic_tmpl.c +index dc2f81b..7f6db92 100644 +--- a/spice-common/common/quic_tmpl.c ++++ b/spice-common/common/quic_tmpl.c +@@ -486,7 +486,11 @@ static void FNAME(uncompress_row_seg)(Encoder *encoder, Channel *channel, + do_run: + state->waitcnt = stopidx - i; + run_index = i; +- run_end = i + decode_channel_run(encoder, channel); ++ run_end = decode_channel_run(encoder, channel); ++ if (run_end < 0 || run_end > (end - i)) { ++ encoder->usr->error(encoder->usr, "wrong RLE\n"); ++ } ++ run_end += i; + + for (; i < run_end; i++) { + UNCOMPRESS_PIX_START(&cur_row[i]); +-- +2.25.4 + diff --git a/SOURCES/0013-quic-Avoid-possible-buffer-overflow-in-find_bucket.patch b/SOURCES/0013-quic-Avoid-possible-buffer-overflow-in-find_bucket.patch new file mode 100644 index 0000000..95c7ad1 --- /dev/null +++ b/SOURCES/0013-quic-Avoid-possible-buffer-overflow-in-find_bucket.patch @@ -0,0 +1,34 @@ +From 57c6e6b00247ad289a27648213d7ad2306fe3931 Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Thu, 30 Apr 2020 10:19:09 +0100 +Subject: [PATCH spice-common 4/4] quic: Avoid possible buffer overflow in + find_bucket + +Proved by fuzzing the code. + +Signed-off-by: Frediano Ziglio +Acked-by: Uri Lublin +--- + common/quic_family_tmpl.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/spice-common/common/quic_family_tmpl.c b/spice-common/common/quic_family_tmpl.c +index 8a5f7d2..6cc051b 100644 +--- a/spice-common/common/quic_family_tmpl.c ++++ b/spice-common/common/quic_family_tmpl.c +@@ -107,7 +107,12 @@ static s_bucket *FNAME(find_bucket)(Channel *channel, const unsigned int val) + spice_assert(val < (0x1U << BPC)); + } + +- return channel->_buckets_ptrs[val]; ++ /* The and (&) here is to avoid buffer overflows in case of garbage or malicious ++ * attempts. Is much faster then using comparisons and save us from such situations. ++ * Note that on normal build the check above won't be compiled as this code path ++ * is pretty hot and would cause speed regressions. ++ */ ++ return channel->_buckets_ptrs[val & ((1U << BPC) - 1)]; + } + + #undef FNAME +-- +2.25.4 diff --git a/SPECS/spice-gtk.spec b/SPECS/spice-gtk.spec index c0f8c16..acfbd08 100644 --- a/SPECS/spice-gtk.spec +++ b/SPECS/spice-gtk.spec @@ -4,7 +4,7 @@ Name: spice-gtk Version: 0.35 -Release: 5%{?dist} +Release: 5%{?dist}.1 Summary: A GTK+ widget for SPICE clients Group: System Environment/Libraries @@ -21,6 +21,10 @@ Patch0006: 0006-channel-usbredir-Add-FIXMEs-on-channel-reset-issues.patch Patch0007: 0007-channel-usbredir-Chain-up-with-parent-s-channel-rese.patch Patch0008: 0008-Detect-timeout-conditions-more-aggressively-on-Linux.patch Patch0009: 0009-Revert-channel-Abort-migration-in-delayed-unref.patch +Patch0010: 0010-quic-Check-we-have-some-data-to-start-decoding-quic-.patch +Patch0011: 0011-quic-Check-image-size-in-quic_decode_begin.patch +Patch0012: 0012-quic-Check-RLE-lengths.patch +Patch0013: 0013-quic-Avoid-possible-buffer-overflow-in-find_bucket.patch BuildRequires: intltool BuildRequires: usbredir-devel >= 0.6-8 @@ -131,6 +135,10 @@ spicy-screenshot is a tool to capture screen-shots of a SPICE desktop. %patch0007 -p1 %patch0008 -p1 %patch0009 -p1 +%patch0010 -p1 +%patch0011 -p1 +%patch0012 -p1 +%patch0013 -p1 %build %configure \ @@ -203,6 +211,10 @@ rm -f %{buildroot}%{_libdir}/*.la %{_bindir}/spicy-stats %changelog +* Wed Sep 2 2020 Frediano Ziglio - 0.35-5.1 +- Fix multiple buffer overflows in QUIC decoding code + Resolves: CVE-2020-14355 + * Tue Oct 15 2019 Victor Toso - 0.35-5 - Keepalive fix Resolves: rhbz#1719736