diff --git a/trunk/CVE-2020-14355.patch b/trunk/CVE-2020-14355.patch new file mode 100644 index 0000000..130b4ee --- /dev/null +++ b/trunk/CVE-2020-14355.patch @@ -0,0 +1,75 @@ +diff --git a/common/quic.c b/common/quic.c +index 55a5d6c..890f128 100644 +--- a/common/quic.c ++++ b/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 */ +@@ -1136,7 +1139,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; + } + +@@ -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)) { +diff --git a/common/quic_family_tmpl.c b/common/quic_family_tmpl.c +index 8a5f7d2..6cc051b 100644 +--- a/common/quic_family_tmpl.c ++++ b/common/quic_family_tmpl.c +@@ -103,7 +103,12 @@ static s_bucket *FNAME(find_bucket)(Channel *channel, const unsigned int val) + { + spice_extra_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 +diff --git a/common/quic_tmpl.c b/common/quic_tmpl.c +index f0a4927..11e09f5 100644 +--- a/common/quic_tmpl.c ++++ b/common/quic_tmpl.c +@@ -570,7 +570,11 @@ static void FNAME_DECL(uncompress_row_seg)(const PIXEL * const prev_row, + do_run: + state->waitcnt = stopidx - i; + run_index = i; +- run_end = i + decode_state_run(encoder, state); ++ run_end = decode_state_run(encoder, state); ++ 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/trunk/PKGBUILD b/trunk/PKGBUILD index b512e2b..bdd1345 100644 --- a/trunk/PKGBUILD +++ b/trunk/PKGBUILD @@ -15,8 +15,17 @@ depends=('gtk3' 'libcacard' 'libjpeg-turbo' 'libpulse' 'opus' 'phodav' 'usbredir makedepends=('gobject-introspection' 'meson' 'spice-protocol' 'usbutils' 'vala') provides=("spice-glib=$pkgver" "spice-gtk3=$pkgver") replaces=('spice-glib' 'spice-gtk3') -source=("https://www.spice-space.org/download/gtk/$pkgname-$pkgver.tar.xz") -sha256sums=('5ae974731baf2b41316d4f0b3ae0c2e47f00bff91a5a617e189cd3dedcd96d8e') +source=("https://www.spice-space.org/download/gtk/$pkgname-$pkgver.tar.xz"{,.sig} + 'CVE-2020-14355.patch') +sha256sums=('5ae974731baf2b41316d4f0b3ae0c2e47f00bff91a5a617e189cd3dedcd96d8e' + 'SKIP' + '11c74ac6a431e284d7f45808b689535cbdaee8d3d0d2220ed7195702f1a573b7') +validpgpkeys=('206D3B352F566F3B0E6572E997D9123DE37A484F') # Victor Toso + +prepare() { + cd $pkgname-$pkgver/subprojects/spice-common + patch -p1 -i "$srcdir"/CVE-2020-14355.patch +} build() { arch-meson $pkgname-$pkgver build -D celt051=disabled