aboutsummaryrefslogtreecommitdiff
path: root/gnu/packages/patches
diff options
context:
space:
mode:
authorMark H Weaver <mhw@netris.org>2017-06-26 00:00:58 -0400
committerMark H Weaver <mhw@netris.org>2017-06-26 00:00:58 -0400
commited068b960eeedb92823238783779730319b8ba0e (patch)
tree36a4de280458d52520b911b2716eb5cea309fd78 /gnu/packages/patches
parenta9308efec642bfbce480545a22fce848e6212456 (diff)
parentffc015bea26f24d862e7e877d907fbe1ab9a9967 (diff)
downloadguix-ed068b960eeedb92823238783779730319b8ba0e.tar
guix-ed068b960eeedb92823238783779730319b8ba0e.tar.gz
Merge branch 'master' into core-updates
Diffstat (limited to 'gnu/packages/patches')
-rw-r--r--gnu/packages/patches/abiword-wmf-version-lookup-fix.patch28
-rw-r--r--gnu/packages/patches/calibre-dont-load-remote-icons.patch45
-rw-r--r--gnu/packages/patches/glibc-CVE-2017-1000366-pt1.patch36
-rw-r--r--gnu/packages/patches/glibc-CVE-2017-1000366-pt2.patch124
-rw-r--r--gnu/packages/patches/glibc-CVE-2017-1000366-pt3.patch206
-rw-r--r--gnu/packages/patches/glibc-vectorized-strcspn-guards.patch23
-rw-r--r--gnu/packages/patches/libwmf-CAN-2004-0941.patch21
-rw-r--r--gnu/packages/patches/libwmf-CVE-2006-3376.patch30
-rw-r--r--gnu/packages/patches/libwmf-CVE-2007-0455.patch15
-rw-r--r--gnu/packages/patches/libwmf-CVE-2007-2756.patch20
-rw-r--r--gnu/packages/patches/libwmf-CVE-2007-3472.patch63
-rw-r--r--gnu/packages/patches/libwmf-CVE-2007-3473.patch17
-rw-r--r--gnu/packages/patches/libwmf-CVE-2007-3477.patch42
-rw-r--r--gnu/packages/patches/libwmf-CVE-2009-1364.patch13
-rw-r--r--gnu/packages/patches/libwmf-CVE-2009-3546.patch17
-rw-r--r--gnu/packages/patches/libwmf-CVE-2015-0848+CVE-2015-4588.patch122
-rw-r--r--gnu/packages/patches/libwmf-CVE-2015-4695.patch60
-rw-r--r--gnu/packages/patches/libwmf-CVE-2015-4696.patch27
-rw-r--r--gnu/packages/patches/qemu-CVE-2017-9524.patch287
19 files changed, 676 insertions, 520 deletions
diff --git a/gnu/packages/patches/abiword-wmf-version-lookup-fix.patch b/gnu/packages/patches/abiword-wmf-version-lookup-fix.patch
deleted file mode 100644
index f27f32f30b..0000000000
--- a/gnu/packages/patches/abiword-wmf-version-lookup-fix.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-The way the configure script determines the version of libwmf is by temporarily
-making dots separator characters, but since the file name of the program which
-returns the version contains dots in Guix (the version in the store entry name),
-doing it this way will always fail.
-
-This is a simple guix-specific fix for the problem.
-
---- a/configure 2010-06-13 23:17:37.000000000 +0200
-+++ b/configure 2014-09-08 17:31:52.102371800 +0200
-@@ -21140,13 +21140,11 @@
- $as_echo "$as_me: WARNING: wmf plugin: program libwmf-config not found in path" >&2;}
- fi
- else
-- IFS_old="$IFS"
-- IFS='.'
-- set -- `$libwmfconfig --version`
-- libwmf_major_found="${1}"
-- libwmf_minor_found="${2}"
-- libwmf_micro_found="${3}"
-- IFS="$IFS_old"
-+ libwmf_fullver_found=`$libwmfconfig --version`
-+ libwmf_major_found=$(echo $libwmf_fullver_found | cut -d . -f 1)
-+ libwmf_minor_found=$(echo $libwmf_fullver_found | cut -d . -f 2)
-+ libwmf_micro_found=$(echo $libwmf_fullver_found | cut -d . -f 3)
-+
- if test "$libwmf_major_found" -gt "$libwmf_major_req"; then
- wmf_deps="yes"
- elif test "$libwmf_major_found" -eq "$libwmf_major_req" &&
diff --git a/gnu/packages/patches/calibre-dont-load-remote-icons.patch b/gnu/packages/patches/calibre-dont-load-remote-icons.patch
deleted file mode 100644
index 2168263072..0000000000
--- a/gnu/packages/patches/calibre-dont-load-remote-icons.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From: Martin Pitt <mpitt@debian.org>
-Date: Mon, 14 Nov 2016 22:41:24 +0100
-Subject: content-server: Don't load external URLs for privacy
-
-Spotted by lintian.
----
- resources/content_server/browse/browse.html | 4 +---
- resources/content_server/index.html | 2 +-
- 2 files changed, 2 insertions(+), 4 deletions(-)
-
-diff --git a/resources/content_server/browse/browse.html b/resources/content_server/browse/browse.html
-index 36f7199..e615707 100644
---- a/resources/content_server/browse/browse.html
-+++ b/resources/content_server/browse/browse.html
-@@ -7,7 +7,7 @@
- <title>..:: calibre {library} ::.. {title}</title>
- <meta http-equiv="X-UA-Compatible" content="IE=100" />
- <meta name="robots" content="noindex" />
-- <link rel="icon" type="image/x-icon" href="//calibre-ebook.com/favicon.ico" />
-+ <link rel="icon" type="image/x-icon" href="favicon.ico" />
-
- <link rel="stylesheet" type="text/css" href="{prefix}/static/browse/browse.css" />
- <link type="text/css" href="{prefix}/static/jquery_ui/css/humanity-custom/jquery-ui-1.8.5.custom.css" rel="stylesheet" />
-@@ -63,8 +63,6 @@
- <input type="image"
- src="{prefix}/static/button-donate.png"
- name="submit"></input>
-- <img alt="" src="https://www.paypal.com/en_US/i/scr/pixel.gif"
-- width="1" height="1"></img>
- </div>
- </form>
- <div id="calibre-home-link" title="Go to the calibre website"></div>
-diff --git a/resources/content_server/index.html b/resources/content_server/index.html
-index 51cc33a..e71d0e8 100644
---- a/resources/content_server/index.html
-+++ b/resources/content_server/index.html
-@@ -9,7 +9,7 @@
- <script type="text/javascript" src="{prefix}/static/date.js" charset="utf-8"></script>
- <script type="text/javascript" src="{prefix}/static/jquery.js" charset="utf-8"></script>
- <script type="text/javascript" src="{prefix}/static/gui.js" charset="utf-8"></script>
-- <link rel="icon" href="//calibre-ebook.com/favicon.ico" type="image/x-icon" />
-+ <link rel="icon" href="favicon.ico" type="image/x-icon" />
- </head>
- <body>
- <div id="banner">
diff --git a/gnu/packages/patches/glibc-CVE-2017-1000366-pt1.patch b/gnu/packages/patches/glibc-CVE-2017-1000366-pt1.patch
new file mode 100644
index 0000000000..71e80968be
--- /dev/null
+++ b/gnu/packages/patches/glibc-CVE-2017-1000366-pt1.patch
@@ -0,0 +1,36 @@
+From f6110a8fee2ca36f8e2d2abecf3cba9fa7b8ea7d Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Mon, 19 Jun 2017 17:09:55 +0200
+Subject: [PATCH] CVE-2017-1000366: Ignore LD_LIBRARY_PATH for AT_SECURE=1
+ programs [BZ #21624]
+
+LD_LIBRARY_PATH can only be used to reorder system search paths, which
+is not useful functionality.
+
+This makes an exploitable unbounded alloca in _dl_init_paths unreachable
+for AT_SECURE=1 programs.
+
+patch from:
+https://sourceware.org/git/?p=glibc.git;a=commit;h=f6110a8fee2ca36f8e2d2abecf3cba9fa7b8ea7d
+---
+ ChangeLog | 7 +++++++
+ elf/rtld.c | 3 ++-
+ 2 files changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/elf/rtld.c b/elf/rtld.c
+index 2446a87..2269dbe 100644
+--- a/elf/rtld.c
++++ b/elf/rtld.c
+@@ -2422,7 +2422,8 @@ process_envvars (enum mode *modep)
+
+ case 12:
+ /* The library search path. */
+- if (memcmp (envline, "LIBRARY_PATH", 12) == 0)
++ if (!__libc_enable_secure
++ && memcmp (envline, "LIBRARY_PATH", 12) == 0)
+ {
+ library_path = &envline[13];
+ break;
+--
+2.9.3
+
diff --git a/gnu/packages/patches/glibc-CVE-2017-1000366-pt2.patch b/gnu/packages/patches/glibc-CVE-2017-1000366-pt2.patch
new file mode 100644
index 0000000000..4b859c4bfd
--- /dev/null
+++ b/gnu/packages/patches/glibc-CVE-2017-1000366-pt2.patch
@@ -0,0 +1,124 @@
+From 6d0ba622891bed9d8394eef1935add53003b12e8 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Mon, 19 Jun 2017 22:31:04 +0200
+Subject: [PATCH] ld.so: Reject overly long LD_PRELOAD path elements
+
+patch from:
+https://sourceware.org/git/?p=glibc.git;a=patch;h=6d0ba622891bed9d8394eef1935add53003b12e8
+
+---
+ ChangeLog | 7 ++++++
+ elf/rtld.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++------------
+ 2 files changed, 73 insertions(+), 16 deletions(-)
+
+diff --git a/elf/rtld.c b/elf/rtld.c
+index 2269dbe..86ae20c 100644
+--- a/elf/rtld.c
++++ b/elf/rtld.c
+@@ -99,6 +99,35 @@ uintptr_t __pointer_chk_guard_local
+ strong_alias (__pointer_chk_guard_local, __pointer_chk_guard)
+ #endif
+
++/* Length limits for names and paths, to protect the dynamic linker,
++ particularly when __libc_enable_secure is active. */
++#ifdef NAME_MAX
++# define SECURE_NAME_LIMIT NAME_MAX
++#else
++# define SECURE_NAME_LIMIT 255
++#endif
++#ifdef PATH_MAX
++# define SECURE_PATH_LIMIT PATH_MAX
++#else
++# define SECURE_PATH_LIMIT 1024
++#endif
++
++/* Check that AT_SECURE=0, or that the passed name does not contain
++ directories and is not overly long. Reject empty names
++ unconditionally. */
++static bool
++dso_name_valid_for_suid (const char *p)
++{
++ if (__glibc_unlikely (__libc_enable_secure))
++ {
++ /* Ignore pathnames with directories for AT_SECURE=1
++ programs, and also skip overlong names. */
++ size_t len = strlen (p);
++ if (len >= SECURE_NAME_LIMIT || memchr (p, '/', len) != NULL)
++ return false;
++ }
++ return *p != '\0';
++}
+
+ /* List of auditing DSOs. */
+ static struct audit_list
+@@ -718,6 +747,42 @@ static const char *preloadlist attribute_relro;
+ /* Nonzero if information about versions has to be printed. */
+ static int version_info attribute_relro;
+
++/* The LD_PRELOAD environment variable gives list of libraries
++ separated by white space or colons that are loaded before the
++ executable's dependencies and prepended to the global scope list.
++ (If the binary is running setuid all elements containing a '/' are
++ ignored since it is insecure.) Return the number of preloads
++ performed. */
++unsigned int
++handle_ld_preload (const char *preloadlist, struct link_map *main_map)
++{
++ unsigned int npreloads = 0;
++ const char *p = preloadlist;
++ char fname[SECURE_PATH_LIMIT];
++
++ while (*p != '\0')
++ {
++ /* Split preload list at space/colon. */
++ size_t len = strcspn (p, " :");
++ if (len > 0 && len < sizeof (fname))
++ {
++ memcpy (fname, p, len);
++ fname[len] = '\0';
++ }
++ else
++ fname[0] = '\0';
++
++ /* Skip over the substring and the following delimiter. */
++ p += len;
++ if (*p != '\0')
++ ++p;
++
++ if (dso_name_valid_for_suid (fname))
++ npreloads += do_preload (fname, main_map, "LD_PRELOAD");
++ }
++ return npreloads;
++}
++
+ static void
+ dl_main (const ElfW(Phdr) *phdr,
+ ElfW(Word) phnum,
+@@ -1464,23 +1529,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
+
+ if (__glibc_unlikely (preloadlist != NULL))
+ {
+- /* The LD_PRELOAD environment variable gives list of libraries
+- separated by white space or colons that are loaded before the
+- executable's dependencies and prepended to the global scope
+- list. If the binary is running setuid all elements
+- containing a '/' are ignored since it is insecure. */
+- char *list = strdupa (preloadlist);
+- char *p;
+-
+ HP_TIMING_NOW (start);
+-
+- /* Prevent optimizing strsep. Speed is not important here. */
+- while ((p = (strsep) (&list, " :")) != NULL)
+- if (p[0] != '\0'
+- && (__builtin_expect (! __libc_enable_secure, 1)
+- || strchr (p, '/') == NULL))
+- npreloads += do_preload (p, main_map, "LD_PRELOAD");
+-
++ npreloads += handle_ld_preload (preloadlist, main_map);
+ HP_TIMING_NOW (stop);
+ HP_TIMING_DIFF (diff, start, stop);
+ HP_TIMING_ACCUM_NT (load_time, diff);
+--
+2.9.3
+
diff --git a/gnu/packages/patches/glibc-CVE-2017-1000366-pt3.patch b/gnu/packages/patches/glibc-CVE-2017-1000366-pt3.patch
new file mode 100644
index 0000000000..3d8f6d2bf8
--- /dev/null
+++ b/gnu/packages/patches/glibc-CVE-2017-1000366-pt3.patch
@@ -0,0 +1,206 @@
+From 81b82fb966ffbd94353f793ad17116c6088dedd9 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Mon, 19 Jun 2017 22:32:12 +0200
+Subject: [PATCH] ld.so: Reject overly long LD_AUDIT path elements
+
+Also only process the last LD_AUDIT entry.
+
+patch from:
+https://sourceware.org/git/?p=glibc.git;a=commit;h=81b82fb966ffbd94353f793ad17116c6088dedd9
+
+---
+ ChangeLog | 11 +++++++
+ elf/rtld.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------
+ 2 files changed, 106 insertions(+), 15 deletions(-)
+
+diff --git a/elf/rtld.c b/elf/rtld.c
+index 86ae20c..65647fb 100644
+--- a/elf/rtld.c
++++ b/elf/rtld.c
+@@ -129,13 +129,91 @@ dso_name_valid_for_suid (const char *p)
+ return *p != '\0';
+ }
+
+-/* List of auditing DSOs. */
++/* LD_AUDIT variable contents. Must be processed before the
++ audit_list below. */
++const char *audit_list_string;
++
++/* Cyclic list of auditing DSOs. audit_list->next is the first
++ element. */
+ static struct audit_list
+ {
+ const char *name;
+ struct audit_list *next;
+ } *audit_list;
+
++/* Iterator for audit_list_string followed by audit_list. */
++struct audit_list_iter
++{
++ /* Tail of audit_list_string still needing processing, or NULL. */
++ const char *audit_list_tail;
++
++ /* The list element returned in the previous iteration. NULL before
++ the first element. */
++ struct audit_list *previous;
++
++ /* Scratch buffer for returning a name which is part of
++ audit_list_string. */
++ char fname[SECURE_NAME_LIMIT];
++};
++
++/* Initialize an audit list iterator. */
++static void
++audit_list_iter_init (struct audit_list_iter *iter)
++{
++ iter->audit_list_tail = audit_list_string;
++ iter->previous = NULL;
++}
++
++/* Iterate through both audit_list_string and audit_list. */
++static const char *
++audit_list_iter_next (struct audit_list_iter *iter)
++{
++ if (iter->audit_list_tail != NULL)
++ {
++ /* First iterate over audit_list_string. */
++ while (*iter->audit_list_tail != '\0')
++ {
++ /* Split audit list at colon. */
++ size_t len = strcspn (iter->audit_list_tail, ":");
++ if (len > 0 && len < sizeof (iter->fname))
++ {
++ memcpy (iter->fname, iter->audit_list_tail, len);
++ iter->fname[len] = '\0';
++ }
++ else
++ /* Do not return this name to the caller. */
++ iter->fname[0] = '\0';
++
++ /* Skip over the substring and the following delimiter. */
++ iter->audit_list_tail += len;
++ if (*iter->audit_list_tail == ':')
++ ++iter->audit_list_tail;
++
++ /* If the name is valid, return it. */
++ if (dso_name_valid_for_suid (iter->fname))
++ return iter->fname;
++ /* Otherwise, wrap around and try the next name. */
++ }
++ /* Fall through to the procesing of audit_list. */
++ }
++
++ if (iter->previous == NULL)
++ {
++ if (audit_list == NULL)
++ /* No pre-parsed audit list. */
++ return NULL;
++ /* Start of audit list. The first list element is at
++ audit_list->next (cyclic list). */
++ iter->previous = audit_list->next;
++ return iter->previous->name;
++ }
++ if (iter->previous == audit_list)
++ /* Cyclic list wrap-around. */
++ return NULL;
++ iter->previous = iter->previous->next;
++ return iter->previous->name;
++}
++
+ #ifndef HAVE_INLINED_SYSCALLS
+ /* Set nonzero during loading and initialization of executable and
+ libraries, cleared before the executable's entry point runs. This
+@@ -1305,11 +1383,13 @@ of this helper program; chances are you did not intend to run this program.\n\
+ GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
+
+ /* If we have auditing DSOs to load, do it now. */
+- if (__glibc_unlikely (audit_list != NULL))
++ bool need_security_init = true;
++ if (__glibc_unlikely (audit_list != NULL)
++ || __glibc_unlikely (audit_list_string != NULL))
+ {
+- /* Iterate over all entries in the list. The order is important. */
+ struct audit_ifaces *last_audit = NULL;
+- struct audit_list *al = audit_list->next;
++ struct audit_list_iter al_iter;
++ audit_list_iter_init (&al_iter);
+
+ /* Since we start using the auditing DSOs right away we need to
+ initialize the data structures now. */
+@@ -1320,9 +1400,14 @@ of this helper program; chances are you did not intend to run this program.\n\
+ use different values (especially the pointer guard) and will
+ fail later on. */
+ security_init ();
++ need_security_init = false;
+
+- do
++ while (true)
+ {
++ const char *name = audit_list_iter_next (&al_iter);
++ if (name == NULL)
++ break;
++
+ int tls_idx = GL(dl_tls_max_dtv_idx);
+
+ /* Now it is time to determine the layout of the static TLS
+@@ -1331,7 +1416,7 @@ of this helper program; chances are you did not intend to run this program.\n\
+ no DF_STATIC_TLS bit is set. The reason is that we know
+ glibc will use the static model. */
+ struct dlmopen_args dlmargs;
+- dlmargs.fname = al->name;
++ dlmargs.fname = name;
+ dlmargs.map = NULL;
+
+ const char *objname;
+@@ -1344,7 +1429,7 @@ of this helper program; chances are you did not intend to run this program.\n\
+ not_loaded:
+ _dl_error_printf ("\
+ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
+- al->name, err_str);
++ name, err_str);
+ if (malloced)
+ free ((char *) err_str);
+ }
+@@ -1448,10 +1533,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
+ goto not_loaded;
+ }
+ }
+-
+- al = al->next;
+ }
+- while (al != audit_list->next);
+
+ /* If we have any auditing modules, announce that we already
+ have two objects loaded. */
+@@ -1715,7 +1797,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
+ if (tcbp == NULL)
+ tcbp = init_tls ();
+
+- if (__glibc_likely (audit_list == NULL))
++ if (__glibc_likely (need_security_init))
+ /* Initialize security features. But only if we have not done it
+ earlier. */
+ security_init ();
+@@ -2346,9 +2428,7 @@ process_dl_audit (char *str)
+ char *p;
+
+ while ((p = (strsep) (&str, ":")) != NULL)
+- if (p[0] != '\0'
+- && (__builtin_expect (! __libc_enable_secure, 1)
+- || strchr (p, '/') == NULL))
++ if (dso_name_valid_for_suid (p))
+ {
+ /* This is using the local malloc, not the system malloc. The
+ memory can never be freed. */
+@@ -2412,7 +2492,7 @@ process_envvars (enum mode *modep)
+ break;
+ }
+ if (memcmp (envline, "AUDIT", 5) == 0)
+- process_dl_audit (&envline[6]);
++ audit_list_string = &envline[6];
+ break;
+
+ case 7:
+--
+2.9.3
+
diff --git a/gnu/packages/patches/glibc-vectorized-strcspn-guards.patch b/gnu/packages/patches/glibc-vectorized-strcspn-guards.patch
new file mode 100644
index 0000000000..3d6c7749d4
--- /dev/null
+++ b/gnu/packages/patches/glibc-vectorized-strcspn-guards.patch
@@ -0,0 +1,23 @@
+Copied from Debian.
+
+2017-06-14 Florian Weimer <fweimer@redhat.com>
+
+ * sysdeps/i386/i686/multiarch/strcspn-c.c: Add IS_IN (libc) guard.
+ * sysdeps/i386/i686/multiarch/varshift.c: Likewise.
+
+--- a/sysdeps/i386/i686/multiarch/strcspn-c.c
++++ b/sysdeps/i386/i686/multiarch/strcspn-c.c
+@@ -1,2 +1,4 @@
+-#define __strcspn_sse2 __strcspn_ia32
+-#include <sysdeps/x86_64/multiarch/strcspn-c.c>
++#if IS_IN (libc)
++# define __strcspn_sse2 __strcspn_ia32
++# include <sysdeps/x86_64/multiarch/strcspn-c.c>
++#endif
+--- a/sysdeps/i386/i686/multiarch/varshift.c
++++ b/sysdeps/i386/i686/multiarch/varshift.c
+@@ -1 +1,3 @@
+-#include <sysdeps/x86_64/multiarch/varshift.c>
++#if IS_IN (libc)
++# include <sysdeps/x86_64/multiarch/varshift.c>
++#endif
diff --git a/gnu/packages/patches/libwmf-CAN-2004-0941.patch b/gnu/packages/patches/libwmf-CAN-2004-0941.patch
deleted file mode 100644
index 84dd9baee6..0000000000
--- a/gnu/packages/patches/libwmf-CAN-2004-0941.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-Copied from Fedora.
-
-http://pkgs.fedoraproject.org/cgit/libwmf.git/tree/libwmf-0.2.8.4-CAN-2004-0941.patch
-
---- libwmf-0.2.8.4/src/extra/gd/gd_png.c 2004-11-11 14:02:37.407589824 -0500
-+++ libwmf-0.2.8.4/src/extra/gd/gd_png.c 2004-11-11 14:04:29.672522960 -0500
-@@ -188,6 +188,14 @@
-
- png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
- &interlace_type, NULL, NULL);
-+ if (overflow2(sizeof (int), width))
-+ {
-+ return NULL;
-+ }
-+ if (overflow2(sizeof (int) * width, height))
-+ {
-+ return NULL;
-+ }
- if ((color_type == PNG_COLOR_TYPE_RGB) ||
- (color_type == PNG_COLOR_TYPE_RGB_ALPHA))
- {
diff --git a/gnu/packages/patches/libwmf-CVE-2006-3376.patch b/gnu/packages/patches/libwmf-CVE-2006-3376.patch
deleted file mode 100644
index 1e0e1ecfa8..0000000000
--- a/gnu/packages/patches/libwmf-CVE-2006-3376.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-Copied from Debian.
-
---- libwmf-0.2.8.4.orig/src/player.c
-+++ libwmf-0.2.8.4/src/player.c
-@@ -23,6 +23,7 @@
-
- #include <stdio.h>
- #include <stdlib.h>
-+#include <stdint.h>
- #include <string.h>
- #include <math.h>
-
-@@ -132,8 +133,14 @@
- }
- }
-
--/* P->Parameters = (unsigned char*) wmf_malloc (API,(MAX_REC_SIZE(API)-3) * 2 * sizeof (unsigned char));
-- */ P->Parameters = (unsigned char*) wmf_malloc (API,(MAX_REC_SIZE(API) ) * 2 * sizeof (unsigned char));
-+ if (MAX_REC_SIZE(API) > UINT32_MAX / 2)
-+ {
-+ API->err = wmf_E_InsMem;
-+ WMF_DEBUG (API,"bailing...");
-+ return (API->err);
-+ }
-+
-+ P->Parameters = (unsigned char*) wmf_malloc (API,(MAX_REC_SIZE(API) ) * 2 * sizeof (unsigned char));
-
- if (ERR (API))
- { WMF_DEBUG (API,"bailing...");
-
diff --git a/gnu/packages/patches/libwmf-CVE-2007-0455.patch b/gnu/packages/patches/libwmf-CVE-2007-0455.patch
deleted file mode 100644
index ceefc75bf2..0000000000
--- a/gnu/packages/patches/libwmf-CVE-2007-0455.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-Copied from Fedora.
-
-http://pkgs.fedoraproject.org/cgit/libwmf.git/tree/libwmf-0.2.8.4-CVE-2007-0455.patch
-
---- libwmf-0.2.8.4/src/extra/gd/gdft.c 2010-12-06 11:18:26.000000000 +0000
-+++ libwmf-0.2.8.4/src/extra/gd/gdft.c 2010-12-06 11:21:09.000000000 +0000
-@@ -811,7 +811,7 @@
- {
- ch = c & 0xFF; /* don't extend sign */
- }
-- next++;
-+ if (*next) next++;
- }
- else
- {
diff --git a/gnu/packages/patches/libwmf-CVE-2007-2756.patch b/gnu/packages/patches/libwmf-CVE-2007-2756.patch
deleted file mode 100644
index feafac535a..0000000000
--- a/gnu/packages/patches/libwmf-CVE-2007-2756.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-Copied from Fedora.
-
-http://pkgs.fedoraproject.org/cgit/libwmf.git/tree/libwmf-0.2.8.4-CVE-2007-2756.patch
-
---- libwmf-0.2.8.4/src/extra/gd/gd_png.c 1 Apr 2007 20:41:01 -0000 1.21.2.1
-+++ libwmf-0.2.8.4/src/extra/gd/gd_png.c 16 May 2007 19:06:11 -0000
-@@ -78,8 +78,11 @@
- gdPngReadData (png_structp png_ptr,
- png_bytep data, png_size_t length)
- {
-- gdGetBuf (data, length, (gdIOCtx *)
-- png_get_io_ptr (png_ptr));
-+ int check;
-+ check = gdGetBuf (data, length, (gdIOCtx *) png_get_io_ptr (png_ptr));
-+ if (check != length) {
-+ png_error(png_ptr, "Read Error: truncated data");
-+ }
- }
-
- static void
diff --git a/gnu/packages/patches/libwmf-CVE-2007-3472.patch b/gnu/packages/patches/libwmf-CVE-2007-3472.patch
deleted file mode 100644
index 180bdb5fc2..0000000000
--- a/gnu/packages/patches/libwmf-CVE-2007-3472.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-Based on a patch from Fedora.
-
-http://pkgs.fedoraproject.org/cgit/libwmf.git/tree/libwmf-0.2.8.4-CVE-2007-3472.patch
-
---- libwmf-0.2.8.4/src/extra/gd/gd.c
-+++ libwmf-0.2.8.4/src/extra/gd/gd.c
-@@ -106,6 +106,18 @@
- gdImagePtr im;
- unsigned long cpa_size;
-
-+ if (overflow2(sx, sy)) {
-+ return NULL;
-+ }
-+
-+ if (overflow2(sizeof (int *), sy)) {
-+ return NULL;
-+ }
-+
-+ if (overflow2(sizeof(int), sx)) {
-+ return NULL;
-+ }
-+
- im = (gdImage *) gdMalloc (sizeof (gdImage));
- if (im == 0) return 0;
- memset (im, 0, sizeof (gdImage));
---- libwmf-0.2.8.4/src/extra/gd/gdhelpers.c 2010-12-06 11:47:31.000000000 +0000
-+++ libwmf-0.2.8.4/src/extra/gd/gdhelpers.c 2010-12-06 11:48:04.000000000 +0000
-@@ -2,6 +2,7 @@
- #include "gdhelpers.h"
- #include <stdlib.h>
- #include <string.h>
-+#include <limits.h>
-
- /* TBB: gd_strtok_r is not portable; provide an implementation */
-
-@@ -94,3 +95,18 @@
- {
- free (ptr);
- }
-+
-+int overflow2(int a, int b)
-+{
-+ if(a < 0 || b < 0) {
-+ fprintf(stderr, "gd warning: one parameter to a memory allocation multiplication is negative, failing operation gracefully\n");
-+ return 1;
-+ }
-+ if(b == 0)
-+ return 0;
-+ if(a > INT_MAX / b) {
-+ fprintf(stderr, "gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully\n");
-+ return 1;
-+ }
-+ return 0;
-+}
---- libwmf-0.2.8.4/src/extra/gd/gdhelpers.h 2010-12-06 11:47:17.000000000 +0000
-+++ libwmf-0.2.8.4/src/extra/gd/gdhelpers.h 2010-12-06 11:48:36.000000000 +0000
-@@ -15,4 +15,6 @@
- void *gdMalloc(size_t size);
- void *gdRealloc(void *ptr, size_t size);
-
-+int overflow2(int a, int b);
-+
- #endif /* GDHELPERS_H */
diff --git a/gnu/packages/patches/libwmf-CVE-2007-3473.patch b/gnu/packages/patches/libwmf-CVE-2007-3473.patch
deleted file mode 100644
index cb96c94a47..0000000000
--- a/gnu/packages/patches/libwmf-CVE-2007-3473.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-Copied from Fedora.
-
-http://pkgs.fedoraproject.org/cgit/libwmf.git/tree/libwmf-0.2.8.4-CVE-2007-3473.patch
-
---- libwmf-0.2.8.4/src/extra/gd/gd.c
-+++ libwmf-0.2.8.4/src/extra/gd/gd.c
-@@ -2483,6 +2483,10 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromXbm (FILE * fd)
- }
- bytes = (w * h / 8) + 1;
- im = gdImageCreate (w, h);
-+ if (!im) {
-+ return 0;
-+ }
-+
- gdImageColorAllocate (im, 255, 255, 255);
- gdImageColorAllocate (im, 0, 0, 0);
- x = 0;
diff --git a/gnu/packages/patches/libwmf-CVE-2007-3477.patch b/gnu/packages/patches/libwmf-CVE-2007-3477.patch
deleted file mode 100644
index e9f6f4278b..0000000000
--- a/gnu/packages/patches/libwmf-CVE-2007-3477.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-Copied from Fedora.
-
-http://pkgs.fedoraproject.org/cgit/libwmf.git/tree/libwmf-0.2.8.4-CVE-2007-3477.patch
-
---- libwmf-0.2.8.4/src/extra/gd/gd.c
-+++ libwmf-0.2.8.4/src/extra/gd/gd.c
-@@ -1335,10 +1335,31 @@
- int w2, h2;
- w2 = w / 2;
- h2 = h / 2;
-- while (e < s)
-- {
-- e += 360;
-- }
-+
-+ if ((s % 360) == (e % 360)) {
-+ s = 0; e = 360;
-+ } else {
-+ if (s > 360) {
-+ s = s % 360;
-+ }
-+
-+ if (e > 360) {
-+ e = e % 360;
-+ }
-+
-+ while (s < 0) {
-+ s += 360;
-+ }
-+
-+ while (e < s) {
-+ e += 360;
-+ }
-+
-+ if (s == e) {
-+ s = 0; e = 360;
-+ }
-+ }
-+
- for (i = s; (i <= e); i++)
- {
- int x, y;
diff --git a/gnu/packages/patches/libwmf-CVE-2009-1364.patch b/gnu/packages/patches/libwmf-CVE-2009-1364.patch
deleted file mode 100644
index 254b821596..0000000000
--- a/gnu/packages/patches/libwmf-CVE-2009-1364.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-Copied from Debian.
-
---- libwmf-0.2.8.4.orig/src/extra/gd/gd_clip.c
-+++ libwmf-0.2.8.4/src/extra/gd/gd_clip.c
-@@ -70,6 +70,7 @@
- { more = gdRealloc (im->clip->list,(im->clip->max + 8) * sizeof (gdClipRectangle));
- if (more == 0) return;
- im->clip->max += 8;
-+ im->clip->list = more;
- }
- im->clip->list[im->clip->count] = (*rect);
- im->clip->count++;
-
diff --git a/gnu/packages/patches/libwmf-CVE-2009-3546.patch b/gnu/packages/patches/libwmf-CVE-2009-3546.patch
deleted file mode 100644
index ef76fe0736..0000000000
--- a/gnu/packages/patches/libwmf-CVE-2009-3546.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-Copied from Fedora.
-
-http://pkgs.fedoraproject.org/cgit/libwmf.git/tree/libwmf-0.2.8.4-CVE-2009-3546.patch
-
---- libwmf-0.2.8.4/src/extra/gd/gd_gd.c 2010-12-06 14:56:06.000000000 +0000
-+++ libwmf-0.2.8.4/src/extra/gd/gd_gd.c 2010-12-06 14:57:04.000000000 +0000
-@@ -42,6 +42,10 @@
- {
- goto fail1;
- }
-+ if (&im->colorsTotal > gdMaxColors)
-+ {
-+ goto fail1;
-+ }
- }
- /* Int to accommodate truecolor single-color transparency */
- if (!gdGetInt (&im->transparent, in))
diff --git a/gnu/packages/patches/libwmf-CVE-2015-0848+CVE-2015-4588.patch b/gnu/packages/patches/libwmf-CVE-2015-0848+CVE-2015-4588.patch
deleted file mode 100644
index 871be1d267..0000000000
--- a/gnu/packages/patches/libwmf-CVE-2015-0848+CVE-2015-4588.patch
+++ /dev/null
@@ -1,122 +0,0 @@
-Copied from Fedora.
-
-http://pkgs.fedoraproject.org/cgit/libwmf.git/tree/libwmf-0.2.8.4-CVE-2015-0848+CVE-2015-4588.patch
-
---- libwmf-0.2.8.4/src/ipa/ipa/bmp.h 2015-06-08 14:46:24.591876404 +0100
-+++ libwmf-0.2.8.4/src/ipa/ipa/bmp.h 2015-06-08 14:46:35.345993247 +0100
-@@ -859,7 +859,7 @@
- %
- %
- */
--static void DecodeImage (wmfAPI* API,wmfBMP* bmp,BMPSource* src,unsigned int compression,unsigned char* pixels)
-+static int DecodeImage (wmfAPI* API,wmfBMP* bmp,BMPSource* src,unsigned int compression,unsigned char* pixels)
- { int byte;
- int count;
- int i;
-@@ -870,12 +870,14 @@
- U32 u;
-
- unsigned char* q;
-+ unsigned char* end;
-
- for (u = 0; u < ((U32) bmp->width * (U32) bmp->height); u++) pixels[u] = 0;
-
- byte = 0;
- x = 0;
- q = pixels;
-+ end = pixels + bmp->width * bmp->height;
-
- for (y = 0; y < bmp->height; )
- { count = ReadBlobByte (src);
-@@ -884,7 +886,10 @@
- { /* Encoded mode. */
- byte = ReadBlobByte (src);
- for (i = 0; i < count; i++)
-- { if (compression == 1)
-+ {
-+ if (q == end)
-+ return 0;
-+ if (compression == 1)
- { (*(q++)) = (unsigned char) byte;
- }
- else
-@@ -896,13 +901,15 @@
- else
- { /* Escape mode. */
- count = ReadBlobByte (src);
-- if (count == 0x01) return;
-+ if (count == 0x01) return 1;
- switch (count)
- {
- case 0x00:
- { /* End of line. */
- x = 0;
- y++;
-+ if (y >= bmp->height)
-+ return 0;
- q = pixels + y * bmp->width;
- break;
- }
-@@ -910,13 +917,20 @@
- { /* Delta mode. */
- x += ReadBlobByte (src);
- y += ReadBlobByte (src);
-+ if (y >= bmp->height)
-+ return 0;
-+ if (x >= bmp->width)
-+ return 0;
- q = pixels + y * bmp->width + x;
- break;
- }
- default:
- { /* Absolute mode. */
- for (i = 0; i < count; i++)
-- { if (compression == 1)
-+ {
-+ if (q == end)
-+ return 0;
-+ if (compression == 1)
- { (*(q++)) = ReadBlobByte (src);
- }
- else
-@@ -943,7 +957,7 @@
- byte = ReadBlobByte (src); /* end of line */
- byte = ReadBlobByte (src);
-
-- return;
-+ return 1;
- }
-
- /*
-@@ -1143,8 +1157,18 @@
- }
- }
- else
-- { /* Convert run-length encoded raster pixels. */
-- DecodeImage (API,bmp,src,(unsigned int) bmp_info.compression,data->image);
-+ {
-+ if (bmp_info.bits_per_pixel == 8) /* Convert run-length encoded raster pixels. */
-+ {
-+ if (!DecodeImage (API,bmp,src,(unsigned int) bmp_info.compression,data->image))
-+ { WMF_ERROR (API,"corrupt bmp");
-+ API->err = wmf_E_BadFormat;
-+ }
-+ }
-+ else
-+ { WMF_ERROR (API,"Unexpected pixel depth");
-+ API->err = wmf_E_BadFormat;
-+ }
- }
-
- if (ERR (API))
---- libwmf-0.2.8.4/src/ipa/ipa.h 2015-06-08 14:46:24.590876393 +0100
-+++ libwmf-0.2.8.4/src/ipa/ipa.h 2015-06-08 14:46:35.345993247 +0100
-@@ -48,7 +48,7 @@
- static unsigned short ReadBlobLSBShort (BMPSource*);
- static unsigned long ReadBlobLSBLong (BMPSource*);
- static long TellBlob (BMPSource*);
--static void DecodeImage (wmfAPI*,wmfBMP*,BMPSource*,unsigned int,unsigned char*);
-+static int DecodeImage (wmfAPI*,wmfBMP*,BMPSource*,unsigned int,unsigned char*);
- static void ReadBMPImage (wmfAPI*,wmfBMP*,BMPSource*);
- static int ExtractColor (wmfAPI*,wmfBMP*,wmfRGB*,unsigned int,unsigned int);
- static void SetColor (wmfAPI*,wmfBMP*,wmfRGB*,unsigned char,unsigned int,unsigned int);
diff --git a/gnu/packages/patches/libwmf-CVE-2015-4695.patch b/gnu/packages/patches/libwmf-CVE-2015-4695.patch
deleted file mode 100644
index 42c4d55f40..0000000000
--- a/gnu/packages/patches/libwmf-CVE-2015-4695.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-Copied from Fedora.
-
-http://pkgs.fedoraproject.org/cgit/libwmf.git/tree/libwmf-0.2.8.4-CVE-2015-4695.patch
-
---- libwmf-0.2.8.4/src/player/meta.h
-+++ libwmf-0.2.8.4/src/player/meta.h
-@@ -1565,7 +1565,7 @@ static int meta_rgn_create (wmfAPI* API,
- objects = P->objects;
-
- i = 0;
-- while (objects[i].type && (i < NUM_OBJECTS (API))) i++;
-+ while ((i < NUM_OBJECTS (API)) && objects[i].type) i++;
-
- if (i == NUM_OBJECTS (API))
- { WMF_ERROR (API,"Object out of range!");
-@@ -2142,7 +2142,7 @@ static int meta_dib_brush (wmfAPI* API,w
- objects = P->objects;
-
- i = 0;
-- while (objects[i].type && (i < NUM_OBJECTS (API))) i++;
-+ while ((i < NUM_OBJECTS (API)) && objects[i].type) i++;
-
- if (i == NUM_OBJECTS (API))
- { WMF_ERROR (API,"Object out of range!");
-@@ -3067,7 +3067,7 @@ static int meta_pen_create (wmfAPI* API,
- objects = P->objects;
-
- i = 0;
-- while (objects[i].type && (i < NUM_OBJECTS (API))) i++;
-+ while ((i < NUM_OBJECTS (API)) && objects[i].type) i++;
-
- if (i == NUM_OBJECTS (API))
- { WMF_ERROR (API,"Object out of range!");
-@@ -3181,7 +3181,7 @@ static int meta_brush_create (wmfAPI* AP
- objects = P->objects;
-
- i = 0;
-- while (objects[i].type && (i < NUM_OBJECTS (API))) i++;
-+ while ((i < NUM_OBJECTS (API)) && objects[i].type) i++;
-
- if (i == NUM_OBJECTS (API))
- { WMF_ERROR (API,"Object out of range!");
-@@ -3288,7 +3288,7 @@ static int meta_font_create (wmfAPI* API
- objects = P->objects;
-
- i = 0;
-- while (objects[i].type && (i < NUM_OBJECTS (API))) i++;
-+ while ((i < NUM_OBJECTS (API)) && objects[i].type) i++;
-
- if (i == NUM_OBJECTS (API))
- { WMF_ERROR (API,"Object out of range!");
-@@ -3396,7 +3396,7 @@ static int meta_palette_create (wmfAPI*
- objects = P->objects;
-
- i = 0;
-- while (objects[i].type && (i < NUM_OBJECTS (API))) i++;
-+ while ((i < NUM_OBJECTS (API)) && objects[i].type) i++;
-
- if (i == NUM_OBJECTS (API))
- { WMF_ERROR (API,"Object out of range!");
diff --git a/gnu/packages/patches/libwmf-CVE-2015-4696.patch b/gnu/packages/patches/libwmf-CVE-2015-4696.patch
deleted file mode 100644
index 3674458c98..0000000000
--- a/gnu/packages/patches/libwmf-CVE-2015-4696.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-Copied from Fedora.
-
-http://pkgs.fedoraproject.org/cgit/libwmf.git/tree/libwmf-0.2.8.4-CVE-2015-4696.patch
-
---- libwmf-0.2.8.4/src/player/meta.h
-+++ libwmf-0.2.8.4/src/player/meta.h
-@@ -2585,6 +2585,8 @@
- polyrect.BR[i] = clip->rects[i].BR;
- }
-
-+ if (FR->region_clip) FR->region_clip (API,&polyrect);
-+
- wmf_free (API,polyrect.TL);
- wmf_free (API,polyrect.BR);
- }
-@@ -2593,9 +2595,10 @@
- polyrect.BR = 0;
-
- polyrect.count = 0;
-+
-+ if (FR->region_clip) FR->region_clip (API,&polyrect);
- }
-
-- if (FR->region_clip) FR->region_clip (API,&polyrect);
-
- return (changed);
- }
diff --git a/gnu/packages/patches/qemu-CVE-2017-9524.patch b/gnu/packages/patches/qemu-CVE-2017-9524.patch
new file mode 100644
index 0000000000..57160055e3
--- /dev/null
+++ b/gnu/packages/patches/qemu-CVE-2017-9524.patch
@@ -0,0 +1,287 @@
+Fix CVE-2017-9524:
+
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9524
+http://seclists.org/oss-sec/2017/q2/454
+
+Patches copied from upstream source repository:
+
+http://git.qemu.org/?p=qemu.git;a=commitdiff;h=df8ad9f128c15aa0a0ebc7b24e9a22c9775b67af
+http://git.qemu.org/?p=qemu.git;a=commitdiff;h=0c9390d978cbf61e8f16c9f580fa96b305c43568
+
+From df8ad9f128c15aa0a0ebc7b24e9a22c9775b67af Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Fri, 26 May 2017 22:04:21 -0500
+Subject: [PATCH] nbd: Fully initialize client in case of failed negotiation
+
+If a non-NBD client connects to qemu-nbd, we would end up with
+a SIGSEGV in nbd_client_put() because we were trying to
+unregister the client's association to the export, even though
+we skipped inserting the client into that list. Easy trigger
+in two terminals:
+
+$ qemu-nbd -p 30001 --format=raw file
+$ nmap 127.0.0.1 -p 30001
+
+nmap claims that it thinks it connected to a pago-services1
+server (which probably means nmap could be updated to learn the
+NBD protocol and give a more accurate diagnosis of the open
+port - but that's not our problem), then terminates immediately,
+so our call to nbd_negotiate() fails. The fix is to reorder
+nbd_co_client_start() to ensure that all initialization occurs
+before we ever try talking to a client in nbd_negotiate(), so
+that the teardown sequence on negotiation failure doesn't fault
+while dereferencing a half-initialized object.
+
+While debugging this, I also noticed that nbd_update_server_watch()
+called by nbd_client_closed() was still adding a channel to accept
+the next client, even when the state was no longer RUNNING. That
+is fixed by making nbd_can_accept() pay attention to the current
+state.
+
+Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1451614
+
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Message-Id: <20170527030421.28366-1-eblake@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ nbd/server.c | 8 +++-----
+ qemu-nbd.c | 2 +-
+ 2 files changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/nbd/server.c b/nbd/server.c
+index ee59e5d234..49b55f6ede 100644
+--- a/nbd/server.c
++++ b/nbd/server.c
+@@ -1358,16 +1358,14 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
+
+ if (exp) {
+ nbd_export_get(exp);
++ QTAILQ_INSERT_TAIL(&exp->clients, client, next);
+ }
++ qemu_co_mutex_init(&client->send_lock);
++
+ if (nbd_negotiate(data)) {
+ client_close(client);
+ goto out;
+ }
+- qemu_co_mutex_init(&client->send_lock);
+-
+- if (exp) {
+- QTAILQ_INSERT_TAIL(&exp->clients, client, next);
+- }
+
+ nbd_client_receive_next_request(client);
+
+diff --git a/qemu-nbd.c b/qemu-nbd.c
+index f60842fd86..651f85ecc1 100644
+--- a/qemu-nbd.c
++++ b/qemu-nbd.c
+@@ -325,7 +325,7 @@ out:
+
+ static int nbd_can_accept(void)
+ {
+- return nb_fds < shared;
++ return state == RUNNING && nb_fds < shared;
+ }
+
+ static void nbd_export_closed(NBDExport *exp)
+--
+2.13.1
+
+From 0c9390d978cbf61e8f16c9f580fa96b305c43568 Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Thu, 8 Jun 2017 17:26:17 -0500
+Subject: [PATCH] nbd: Fix regression on resiliency to port scan
+
+Back in qemu 2.5, qemu-nbd was immune to port probes (a transient
+server would not quit, regardless of how many probe connections
+came and went, until a connection actually negotiated). But we
+broke that in commit ee7d7aa when removing the return value to
+nbd_client_new(), although that patch also introduced a bug causing
+an assertion failure on a client that fails negotiation. We then
+made it worse during refactoring in commit 1a6245a (a segfault
+before we could even assert); the (masked) assertion was cleaned
+up in d3780c2 (still in 2.6), and just recently we finally fixed
+the segfault ("nbd: Fully intialize client in case of failed
+negotiation"). But that still means that ever since we added
+TLS support to qemu-nbd, we have been vulnerable to an ill-timed
+port-scan being able to cause a denial of service by taking down
+qemu-nbd before a real client has a chance to connect.
+
+Since negotiation is now handled asynchronously via coroutines,
+we no longer have a synchronous point of return by re-adding a
+return value to nbd_client_new(). So this patch instead wires
+things up to pass the negotiation status through the close_fn
+callback function.
+
+Simple test across two terminals:
+$ qemu-nbd -f raw -p 30001 file
+$ nmap 127.0.0.1 -p 30001 && \
+ qemu-io -c 'r 0 512' -f raw nbd://localhost:30001
+
+Note that this patch does not change what constitutes successful
+negotiation (thus, a client must enter transmission phase before
+that client can be considered as a reason to terminate the server
+when the connection ends). Perhaps we may want to tweak things
+in a later patch to also treat a client that uses NBD_OPT_ABORT
+as being a 'successful' negotiation (the client correctly talked
+the NBD protocol, and informed us it was not going to use our
+export after all), but that's a discussion for another day.
+
+Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1451614
+
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Message-Id: <20170608222617.20376-1-eblake@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ blockdev-nbd.c | 6 +++++-
+ include/block/nbd.h | 2 +-
+ nbd/server.c | 24 +++++++++++++++---------
+ qemu-nbd.c | 4 ++--
+ 4 files changed, 23 insertions(+), 13 deletions(-)
+
+diff --git a/blockdev-nbd.c b/blockdev-nbd.c
+index dd0860f4a6..28f551a7b0 100644
+--- a/blockdev-nbd.c
++++ b/blockdev-nbd.c
+@@ -27,6 +27,10 @@ typedef struct NBDServerData {
+
+ static NBDServerData *nbd_server;
+
++static void nbd_blockdev_client_closed(NBDClient *client, bool ignored)
++{
++ nbd_client_put(client);
++}
+
+ static gboolean nbd_accept(QIOChannel *ioc, GIOCondition condition,
+ gpointer opaque)
+@@ -46,7 +50,7 @@ static gboolean nbd_accept(QIOChannel *ioc, GIOCondition condition,
+ qio_channel_set_name(QIO_CHANNEL(cioc), "nbd-server");
+ nbd_client_new(NULL, cioc,
+ nbd_server->tlscreds, NULL,
+- nbd_client_put);
++ nbd_blockdev_client_closed);
+ object_unref(OBJECT(cioc));
+ return TRUE;
+ }
+diff --git a/include/block/nbd.h b/include/block/nbd.h
+index 416257abca..8fa5ce51f3 100644
+--- a/include/block/nbd.h
++++ b/include/block/nbd.h
+@@ -162,7 +162,7 @@ void nbd_client_new(NBDExport *exp,
+ QIOChannelSocket *sioc,
+ QCryptoTLSCreds *tlscreds,
+ const char *tlsaclname,
+- void (*close)(NBDClient *));
++ void (*close_fn)(NBDClient *, bool));
+ void nbd_client_get(NBDClient *client);
+ void nbd_client_put(NBDClient *client);
+
+diff --git a/nbd/server.c b/nbd/server.c
+index 49b55f6ede..f2b1aa47ce 100644
+--- a/nbd/server.c
++++ b/nbd/server.c
+@@ -81,7 +81,7 @@ static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);
+
+ struct NBDClient {
+ int refcount;
+- void (*close)(NBDClient *client);
++ void (*close_fn)(NBDClient *client, bool negotiated);
+
+ bool no_zeroes;
+ NBDExport *exp;
+@@ -778,7 +778,7 @@ void nbd_client_put(NBDClient *client)
+ }
+ }
+
+-static void client_close(NBDClient *client)
++static void client_close(NBDClient *client, bool negotiated)
+ {
+ if (client->closing) {
+ return;
+@@ -793,8 +793,8 @@ static void client_close(NBDClient *client)
+ NULL);
+
+ /* Also tell the client, so that they release their reference. */
+- if (client->close) {
+- client->close(client);
++ if (client->close_fn) {
++ client->close_fn(client, negotiated);
+ }
+ }
+
+@@ -975,7 +975,7 @@ void nbd_export_close(NBDExport *exp)
+
+ nbd_export_get(exp);
+ QTAILQ_FOREACH_SAFE(client, &exp->clients, next, next) {
+- client_close(client);
++ client_close(client, true);
+ }
+ nbd_export_set_name(exp, NULL);
+ nbd_export_set_description(exp, NULL);
+@@ -1337,7 +1337,7 @@ done:
+
+ out:
+ nbd_request_put(req);
+- client_close(client);
++ client_close(client, true);
+ nbd_client_put(client);
+ }
+
+@@ -1363,7 +1363,7 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
+ qemu_co_mutex_init(&client->send_lock);
+
+ if (nbd_negotiate(data)) {
+- client_close(client);
++ client_close(client, false);
+ goto out;
+ }
+
+@@ -1373,11 +1373,17 @@ out:
+ g_free(data);
+ }
+
++/*
++ * Create a new client listener on the given export @exp, using the
++ * given channel @sioc. Begin servicing it in a coroutine. When the
++ * connection closes, call @close_fn with an indication of whether the
++ * client completed negotiation.
++ */
+ void nbd_client_new(NBDExport *exp,
+ QIOChannelSocket *sioc,
+ QCryptoTLSCreds *tlscreds,
+ const char *tlsaclname,
+- void (*close_fn)(NBDClient *))
++ void (*close_fn)(NBDClient *, bool))
+ {
+ NBDClient *client;
+ NBDClientNewData *data = g_new(NBDClientNewData, 1);
+@@ -1394,7 +1400,7 @@ void nbd_client_new(NBDExport *exp,
+ object_ref(OBJECT(client->sioc));
+ client->ioc = QIO_CHANNEL(sioc);
+ object_ref(OBJECT(client->ioc));
+- client->close = close_fn;
++ client->close_fn = close_fn;
+
+ data->client = client;
+ data->co = qemu_coroutine_create(nbd_co_client_start, data);
+diff --git a/qemu-nbd.c b/qemu-nbd.c
+index 651f85ecc1..9464a0461c 100644
+--- a/qemu-nbd.c
++++ b/qemu-nbd.c
+@@ -336,10 +336,10 @@ static void nbd_export_closed(NBDExport *exp)
+
+ static void nbd_update_server_watch(void);
+
+-static void nbd_client_closed(NBDClient *client)
++static void nbd_client_closed(NBDClient *client, bool negotiated)
+ {
+ nb_fds--;
+- if (nb_fds == 0 && !persistent && state == RUNNING) {
++ if (negotiated && nb_fds == 0 && !persistent && state == RUNNING) {
+ state = TERMINATE;
+ }
+ nbd_update_server_watch();
+--
+2.13.1
+