diff options
Diffstat (limited to 'gnu/packages/patches')
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 + |