diff options
Diffstat (limited to 'gnu/packages/patches/libxv-CVE-2016-5407.patch')
-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 + |