summary refs log tree commit diff
path: root/gnu/packages/patches
diff options
context:
space:
mode:
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
+