diff options
author | Leo Famulari <leo@famulari.name> | 2016-10-05 13:30:39 -0400 |
---|---|---|
committer | Leo Famulari <leo@famulari.name> | 2016-10-05 17:37:22 -0400 |
commit | e73631a906429bbaccfaafdb24070260bc914d8d (patch) | |
tree | 3b2fc024036e6b424278d25d7f18ed3a78f6ffb9 /gnu/packages/patches | |
parent | 1f90b80f8bf776cce5c312b3c519c3fa79fc79f5 (diff) | |
download | guix-e73631a906429bbaccfaafdb24070260bc914d8d.tar.gz |
gnu: libxv: Fix CVE-2016-5407.
* gnu/packages/patches/libxv-CVE-2016-5407.patch: New file. * gnu/local.mk (dist_patch_DATA): Add it. * gnu/packages/xorg.scm (libxv)[replacement]: New field. (libxv/fixed): New variable.
Diffstat (limited to 'gnu/packages/patches')
-rw-r--r-- | gnu/packages/patches/libxv-CVE-2016-5407.patch | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/gnu/packages/patches/libxv-CVE-2016-5407.patch b/gnu/packages/patches/libxv-CVE-2016-5407.patch new file mode 100644 index 0000000000..e6a76c9f70 --- /dev/null +++ b/gnu/packages/patches/libxv-CVE-2016-5407.patch @@ -0,0 +1,162 @@ +Fix CVE-2016-5407: + +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5407 + +Patch copied from upstream source repository: + +https://cgit.freedesktop.org/xorg/lib/libXv/commit/?id=d9da580b46a28ab497de2e94fdc7b9ff953dab17 + +From d9da580b46a28ab497de2e94fdc7b9ff953dab17 Mon Sep 17 00:00:00 2001 +From: Tobias Stoeckmann <tobias@stoeckmann.org> +Date: Sun, 25 Sep 2016 21:30:03 +0200 +Subject: [PATCH] Protocol handling issues in libXv - CVE-2016-5407 + +The Xv query functions for adaptors and encodings suffer from out of +boundary accesses if a hostile X server sends a maliciously crafted +response. + +A previous fix already checks the received length against fixed values +but ignores additional length specifications which are stored inside +the received data. + +These lengths are accessed in a for-loop. The easiest way to guarantee +a correct processing is by validating all lengths against the +remaining size left before accessing referenced memory. + +This makes the previously applied check obsolete, therefore I removed +it. + +Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org> +Reviewed-by: Matthieu Herrb <matthieu@herrb.eu> +--- + src/Xv.c | 46 +++++++++++++++++++++++++++++----------------- + 1 file changed, 29 insertions(+), 17 deletions(-) + +diff --git a/src/Xv.c b/src/Xv.c +index e47093a..be450c4 100644 +--- a/src/Xv.c ++++ b/src/Xv.c +@@ -158,6 +158,7 @@ XvQueryAdaptors( + size_t size; + unsigned int ii, jj; + char *name; ++ char *end; + XvAdaptorInfo *pas = NULL, *pa; + XvFormat *pfs, *pf; + char *buffer = NULL; +@@ -197,17 +198,13 @@ XvQueryAdaptors( + /* GET INPUT ADAPTORS */ + + if (rep.num_adaptors == 0) { +- /* If there's no adaptors, there's nothing more to do. */ ++ /* If there are no adaptors, there's nothing more to do. */ + status = Success; + goto out; + } + +- if (size < (rep.num_adaptors * sz_xvAdaptorInfo)) { +- /* If there's not enough data for the number of adaptors, +- then we have a problem. */ +- status = XvBadReply; +- goto out; +- } ++ u.buffer = buffer; ++ end = buffer + size; + + size = rep.num_adaptors * sizeof(XvAdaptorInfo); + if ((pas = Xmalloc(size)) == NULL) { +@@ -225,9 +222,12 @@ XvQueryAdaptors( + pa++; + } + +- u.buffer = buffer; + pa = pas; + for (ii = 0; ii < rep.num_adaptors; ii++) { ++ if (u.buffer + sz_xvAdaptorInfo > end) { ++ status = XvBadReply; ++ goto out; ++ } + pa->type = u.pa->type; + pa->base_id = u.pa->base_id; + pa->num_ports = u.pa->num_ports; +@@ -239,6 +239,10 @@ XvQueryAdaptors( + size = u.pa->name_size; + u.buffer += pad_to_int32(sz_xvAdaptorInfo); + ++ if (u.buffer + size > end) { ++ status = XvBadReply; ++ goto out; ++ } + if ((name = Xmalloc(size + 1)) == NULL) { + status = XvBadAlloc; + goto out; +@@ -259,6 +263,11 @@ XvQueryAdaptors( + + pf = pfs; + for (jj = 0; jj < pa->num_formats; jj++) { ++ if (u.buffer + sz_xvFormat > end) { ++ Xfree(pfs); ++ status = XvBadReply; ++ goto out; ++ } + pf->depth = u.pf->depth; + pf->visual_id = u.pf->visual; + pf++; +@@ -327,6 +336,7 @@ XvQueryEncodings( + size_t size; + unsigned int jj; + char *name; ++ char *end; + XvEncodingInfo *pes = NULL, *pe; + char *buffer = NULL; + union { +@@ -364,17 +374,13 @@ XvQueryEncodings( + /* GET ENCODINGS */ + + if (rep.num_encodings == 0) { +- /* If there's no encodings, there's nothing more to do. */ ++ /* If there are no encodings, there's nothing more to do. */ + status = Success; + goto out; + } + +- if (size < (rep.num_encodings * sz_xvEncodingInfo)) { +- /* If there's not enough data for the number of adaptors, +- then we have a problem. */ +- status = XvBadReply; +- goto out; +- } ++ u.buffer = buffer; ++ end = buffer + size; + + size = rep.num_encodings * sizeof(XvEncodingInfo); + if ((pes = Xmalloc(size)) == NULL) { +@@ -391,10 +397,12 @@ XvQueryEncodings( + pe++; + } + +- u.buffer = buffer; +- + pe = pes; + for (jj = 0; jj < rep.num_encodings; jj++) { ++ if (u.buffer + sz_xvEncodingInfo > end) { ++ status = XvBadReply; ++ goto out; ++ } + pe->encoding_id = u.pe->encoding; + pe->width = u.pe->width; + pe->height = u.pe->height; +@@ -405,6 +413,10 @@ XvQueryEncodings( + size = u.pe->name_size; + u.buffer += pad_to_int32(sz_xvEncodingInfo); + ++ if (u.buffer + size > end) { ++ status = XvBadReply; ++ goto out; ++ } + if ((name = Xmalloc(size + 1)) == NULL) { + status = XvBadAlloc; + goto out; +-- +2.10.1 + |