commit nbd for openSUSE:Factory
Hello community, here is the log from the commit of package nbd for openSUSE:Factory checked in at 2015-05-29 10:42:58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/nbd (Old) and /work/SRC/openSUSE:Factory/.nbd.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "nbd" Changes: -------- --- /work/SRC/openSUSE:Factory/nbd/nbd.changes 2015-05-15 07:43:19.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.nbd.new/nbd.changes 2015-05-29 10:43:00.000000000 +0200 @@ -1,0 +2,10 @@ +Thu May 28 11:32:18 UTC 2015 - mpluskal@suse.com + +- Update to 3.11 + * nbd-server: fix unsafe signal handling + * define error values as part of the protocol + * docs/proto: clarify NBD_CMD_FLUSH +- Drop nbd_signaling_CVE-2015-0847.patch as fix is included in + upstream + +------------------------------------------------------------------- Old: ---- nbd-3.10.tar.xz nbd_signaling_CVE-2015-0847.patch New: ---- nbd-3.11.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ nbd.spec ++++++ --- /var/tmp/diff_new_pack.xjx5An/_old 2015-05-29 10:43:01.000000000 +0200 +++ /var/tmp/diff_new_pack.xjx5An/_new 2015-05-29 10:43:01.000000000 +0200 @@ -17,7 +17,7 @@ Name: nbd -Version: 3.10 +Version: 3.11 Release: 0 Summary: Network Block Device Server and Client Utilities License: GPL-2.0+ @@ -32,8 +32,6 @@ Patch3: nbd-2.9.25-doxyfile.diff # fix return value Patch4: no-return-nonvoid.patch -# fix for CVE-2015-0847 (incorrect signal handling DoD) -Patch5: nbd_signaling_CVE-2015-0847.patch BuildRequires: doxygen BuildRequires: glib2-devel >= 2.26.0 BuildRequires: xz @@ -91,7 +89,6 @@ %patch2 -p1 %patch3 -p1 %patch4 -p1 -%patch5 -p1 %build export CFLAGS="%{optflags} -fstack-protector -fno-strict-aliasing" ++++++ nbd-2.9.25-close.diff ++++++ --- /var/tmp/diff_new_pack.xjx5An/_old 2015-05-29 10:43:01.000000000 +0200 +++ /var/tmp/diff_new_pack.xjx5An/_new 2015-05-29 10:43:01.000000000 +0200 @@ -1,7 +1,7 @@ -Index: nbd-3.9/nbd-client.c +Index: nbd-3.11/nbd-client.c =================================================================== ---- nbd-3.9.orig/nbd-client.c -+++ nbd-3.9/nbd-client.c +--- nbd-3.11.orig/nbd-client.c ++++ nbd-3.11/nbd-client.c @@ -79,6 +79,7 @@ int check_conn(char* devname, int do_pri } buf[(len < 256) ? len : 255]='\0'; ++++++ nbd-2.9.25-doxyfile.diff ++++++ --- /var/tmp/diff_new_pack.xjx5An/_old 2015-05-29 10:43:01.000000000 +0200 +++ /var/tmp/diff_new_pack.xjx5An/_new 2015-05-29 10:43:01.000000000 +0200 @@ -1,6 +1,8 @@ ---- nbd-2.9.25/doc/Doxyfile.in 2011-10-01 06:28:58.000000000 -0400 -+++ nbd-2.9.20/Doxyfile.in 2009-01-03 07:59:46.000000000 -0500 -@@ -30,7 +30,7 @@ +Index: nbd-3.11/doc/Doxyfile.in +=================================================================== +--- nbd-3.11.orig/doc/Doxyfile.in ++++ nbd-3.11/doc/Doxyfile.in +@@ -30,7 +30,7 @@ PROJECT_NUMBER = @PACKAGE_VERSIO # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. @@ -9,7 +11,7 @@ # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output -@@ -459,7 +459,7 @@ +@@ -459,7 +459,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. ++++++ nbd-3.10.tar.xz -> nbd-3.11.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nbd-3.10/configure new/nbd-3.11/configure --- old/nbd-3.10/configure 2015-03-11 18:32:38.000000000 +0100 +++ new/nbd-3.11/configure 2015-05-25 12:28:35.000000000 +0200 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for nbd 3.10. +# Generated by GNU Autoconf 2.69 for nbd 3.11. # # Report bugs to <wouter@debian.org>. # @@ -590,8 +590,8 @@ # Identity of this package. PACKAGE_NAME='nbd' PACKAGE_TARNAME='nbd' -PACKAGE_VERSION='3.10' -PACKAGE_STRING='nbd 3.10' +PACKAGE_VERSION='3.11' +PACKAGE_STRING='nbd 3.11' PACKAGE_BUGREPORT='wouter@debian.org' PACKAGE_URL='' @@ -1335,7 +1335,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures nbd 3.10 to adapt to many kinds of systems. +\`configure' configures nbd 3.11 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1405,7 +1405,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of nbd 3.10:";; + short | recursive ) echo "Configuration of nbd 3.11:";; esac cat <<\_ACEOF @@ -1529,7 +1529,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -nbd configure 3.10 +nbd configure 3.11 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2238,7 +2238,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by nbd $as_me 3.10, which was +It was created by nbd $as_me 3.11, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3101,7 +3101,7 @@ # Define the identity of the package. PACKAGE='nbd' - VERSION='3.10' + VERSION='3.11' cat >>confdefs.h <<_ACEOF @@ -14431,7 +14431,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by nbd $as_me 3.10, which was +This file was extended by nbd $as_me 3.11, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14497,7 +14497,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -nbd config.status 3.10 +nbd config.status 3.11 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nbd-3.10/configure.ac new/nbd-3.11/configure.ac --- old/nbd-3.10/configure.ac 2015-03-11 18:31:55.000000000 +0100 +++ new/nbd-3.11/configure.ac 2015-05-25 12:28:03.000000000 +0200 @@ -1,7 +1,7 @@ dnl Configure script for NBD system dnl (c) 1998 Martin Mares <mj@ucw.cz>, (c) 2000 Pavel Machek <pavel@ucw.cz>, dnl (c) 2003-2006 Wouter Verhelst <wouter@debian.org> -AC_INIT([nbd],[3.10],[wouter@debian.org]) +AC_INIT([nbd],[3.11],[wouter@debian.org]) AM_INIT_AUTOMAKE(foreign dist-xz serial-tests) AM_MAINTAINER_MODE([enable]) LT_INIT diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nbd-3.10/doc/proto.txt new/nbd-3.11/doc/proto.txt --- old/nbd-3.10/doc/proto.txt 2015-03-11 18:31:55.000000000 +0100 +++ new/nbd-3.11/doc/proto.txt 2015-05-25 12:27:56.000000000 +0200 @@ -43,7 +43,7 @@ The reply contains three fields: a 32 bit magic number ('magic'), a 32 bit error code ('error'; 0, unless an error occurred in which case it is -the errno of the error on the server side), and the same 64 bit handle +one of the error values documented below), and the same 64 bit handle that the corresponding request had in its 'handle' field. In case the reply is sent in response to a read request and the error field is 0 (zero), the reply header is immediately followed by request.len bytes of @@ -65,6 +65,30 @@ in a multifile environment). NBD_CMD_FLAG_FUA will not be set unless NBD_FLAG_SEND_FUA is set. +Error values +------------ + +The following error values are defined: + + Integer value Short name Description + ------------------------------------------------------------- + 1 EPERM Operation not permitted + 5 EIO Input/output error + 12 ENOMEM Cannot allocate memory + 22 EINVAL Invalid argument + 28 ENOSPC No space left on device + +The server should return ENOSPC if it receives a write request including +one or more sectors beyond the size of the device. It should return +EINVAL if it receives a read or trim request including one or more +sectors beyond the size of the device. It also should map the EDQUOT +and EFBIG errors to ENOSPC. Finally, it should return EPERM if it +receives a write or trim request on a read-only export. Which error to +return in any other case is not specified by the NBD protocol. + +Negotiation +=========== + There are two versions of the negotiation: the 'old' style (nbd <= 2.9.16) and the 'new' style (nbd >= 2.9.17, though due to a bug it does not work with anything below 2.9.18). What follows is a description of @@ -334,9 +358,9 @@ NBD_CMD_DISC command. * NBD_CMD_FLUSH (3) - A flush request; a write barrier. The server MUST NOT send the reply - header to this request before all outstanding write requests that were - sent before this command have hit the disk (using fsync() or similar). + A flush request; a write barrier. The server MUST NOT send a successful + reply header for this request before all write requests that were + completed before this command have hit the disk (using fsync() or similar). In this command, "len" and "offset" are reserved, and should be set to all-zero. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nbd-3.10/nbd-server.c new/nbd-3.11/nbd-server.c --- old/nbd-3.10/nbd-server.c 2015-03-16 18:51:04.000000000 +0100 +++ new/nbd-3.11/nbd-server.c 2015-05-25 12:27:56.000000000 +0200 @@ -168,6 +168,16 @@ #include <nbdsrv.h> +static volatile sig_atomic_t is_sigchld_caught; /**< Flag set by + SIGCHLD handler + to mark a child + exit */ + +static volatile sig_atomic_t is_sigterm_caught; /**< Flag set by + SIGTERM handler + to mark a exit + request */ + static volatile sig_atomic_t is_sighup_caught; /**< Flag set by SIGHUP handler to mark a reconfiguration @@ -930,27 +940,16 @@ } /** - * Signal handler for SIGCHLD + * Handle SIGCHLD by setting atomically a flag which will be evaluated in the + * main loop of the root server process. This allows us to separate the signal + * catching from th actual task triggered by SIGCHLD and hence processing in the + * interrupt context is kept as minimial as possible. + * * @param s the signal we're handling (must be SIGCHLD, or something * is severely wrong) **/ -void sigchld_handler(int s) { - int status; - int* i; - pid_t pid; - - while((pid=waitpid(-1, &status, WNOHANG)) > 0) { - if(WIFEXITED(status)) { - msg(LOG_INFO, "Child exited with %d", WEXITSTATUS(status)); - } - i=g_hash_table_lookup(children, &pid); - if(!i) { - msg(LOG_INFO, "SIGCHLD received for an unknown child with PID %ld", (long)pid); - } else { - DEBUG("Removing %d from the list of children", pid); - g_hash_table_remove(children, &pid); - } - } +static void sigchld_handler(const int s G_GNUC_UNUSED) { + is_sigchld_caught = 1; } /** @@ -968,15 +967,16 @@ } /** - * Handle SIGTERM and dispatch it to our children + * Handle SIGTERM by setting atomically a flag which will be evaluated in the + * main loop of the root server process. This allows us to separate the signal + * catching from th actual task triggered by SIGTERM and hence processing in the + * interrupt context is kept as minimial as possible. + * * @param s the signal we're handling (must be SIGTERM, or something * is severely wrong). **/ -void sigterm_handler(int s) { - g_hash_table_foreach(children, killchild, NULL); - unlink(pidfname); - - exit(EXIT_SUCCESS); +static void sigterm_handler(const int s G_GNUC_UNUSED) { + is_sigterm_caught = 1; } /** @@ -1554,12 +1554,33 @@ } } +static int nbd_errno(int errcode) { + switch (errcode) { + case EPERM: + return htonl(1); + case EIO: + return htonl(5); + case ENOMEM: + return htonl(12); + case EINVAL: + return htonl(22); + case EFBIG: + case ENOSPC: +#ifdef EDQUOT + case EDQUOT: +#endif + return htonl(28); // ENOSPC + default: + return htonl(22); // EINVAL + } +} + /** sending macro. */ #define SEND(net,reply) { writeit( net, &reply, sizeof( reply )); \ if (client->transactionlogfd != -1) \ writeit(client->transactionlogfd, &reply, sizeof(reply)); } /** error macro. */ -#define ERROR(client,reply,errcode) { reply.error = htonl(errcode); SEND(client->net,reply); reply.error = 0; } +#define ERROR(client,reply,errcode) { reply.error = nbd_errno(errcode); SEND(client->net,reply); reply.error = 0; } /** * Serve a file to a single client. * @@ -1609,7 +1630,8 @@ memcpy(reply.handle, request.handle, sizeof(reply.handle)); - if ((command==NBD_CMD_WRITE) || (command==NBD_CMD_READ)) { + if ((command==NBD_CMD_WRITE) || (command==NBD_CMD_READ) || + (command==NBD_CMD_TRIM)) { if (request.from + len < request.from) { // 64 bit overflow!! DEBUG("[Number too large!]"); ERROR(client, reply, EINVAL); @@ -1618,7 +1640,7 @@ if (((off_t)request.from + len) > client->exportsize) { DEBUG("[RANGE!]"); - ERROR(client, reply, EINVAL); + ERROR(client, reply, (command==NBD_CMD_WRITE) ? ENOSPC : EINVAL); continue; } @@ -1711,6 +1733,12 @@ case NBD_CMD_TRIM: /* The kernel module sets discard_zeroes_data == 0, * so it is okay to do nothing. */ + if ((client->server->flags & F_READONLY) || + (client->server->flags & F_AUTOREADONLY)) { + DEBUG("[TRIM to READONLY!]"); + ERROR(client, reply, EPERM); + continue; + } if (exptrim(&request, client)) { DEBUG("Trim failed: %m"); ERROR(client, reply, errno); @@ -2065,9 +2093,12 @@ goto out; } /* Child */ + + /* Child's signal disposition is reset to default. */ signal(SIGCHLD, SIG_DFL); signal(SIGTERM, SIG_DFL); signal(SIGHUP, SIG_DFL); + sigemptyset(&oldset); out: sigprocmask(SIG_SETMASK, &oldset, NULL); return pid; @@ -2261,9 +2292,12 @@ goto handle_connection_out; } /* child */ + + /* Child's signal disposition is reset to default. */ signal(SIGCHLD, SIG_DFL); signal(SIGTERM, SIG_DFL); signal(SIGHUP, SIG_DFL); + sigemptyset(&oldset); sigprocmask(SIG_SETMASK, &oldset, NULL); g_hash_table_destroy(children); @@ -2367,6 +2401,8 @@ int max; fd_set mset; fd_set rset; + sigset_t blocking_mask; + sigset_t original_mask; /* * Set up the master fd_set. The set of descriptors we need @@ -2389,7 +2425,56 @@ FD_SET(sock, &mset); max=sock>max?sock:max; } + + /* Construct a signal mask which is used to make signal testing and + * receiving an atomic operation to ensure no signal is received between + * tests and blocking pselect(). */ + if (sigemptyset(&blocking_mask) == -1) + err("failed to initialize blocking_mask: %m"); + + if (sigaddset(&blocking_mask, SIGCHLD) == -1) + err("failed to add SIGCHLD to blocking_mask: %m"); + + if (sigaddset(&blocking_mask, SIGHUP) == -1) + err("failed to add SIGHUP to blocking_mask: %m"); + + if (sigaddset(&blocking_mask, SIGTERM) == -1) + err("failed to add SIGTERM to blocking_mask: %m"); + + if (sigprocmask(SIG_BLOCK, &blocking_mask, &original_mask) == -1) + err("failed to block signals: %m"); + for(;;) { + if (is_sigterm_caught) { + is_sigterm_caught = 0; + + g_hash_table_foreach(children, killchild, NULL); + unlink(pidfname); + + exit(EXIT_SUCCESS); + } + + if (is_sigchld_caught) { + int status; + int* i; + pid_t pid; + + is_sigchld_caught = 0; + + while ((pid=waitpid(-1, &status, WNOHANG)) > 0) { + if (WIFEXITED(status)) { + msg(LOG_INFO, "Child exited with %d", WEXITSTATUS(status)); + } + i = g_hash_table_lookup(children, &pid); + if (!i) { + msg(LOG_INFO, "SIGCHLD received for an unknown child with PID %ld", (long)pid); + } else { + DEBUG("Removing %d from the list of children", pid); + g_hash_table_remove(children, &pid); + } + } + } + /* SIGHUP causes the root server process to reconfigure * itself and add new export servers for each newly * found export configuration group, i.e. spawn new @@ -2424,8 +2509,7 @@ } memcpy(&rset, &mset, sizeof(fd_set)); - if(select(max+1, &rset, NULL, NULL, NULL)>0) { - + if (pselect(max + 1, &rset, NULL, NULL, NULL, &original_mask) > 0) { DEBUG("accept, "); for(i=0; i < modernsocks->len; i++) { int sock = g_array_index(modernsocks, int, i); ++++++ no-return-nonvoid.patch ++++++ --- /var/tmp/diff_new_pack.xjx5An/_old 2015-05-29 10:43:01.000000000 +0200 +++ /var/tmp/diff_new_pack.xjx5An/_new 2015-05-29 10:43:01.000000000 +0200 @@ -1,7 +1,7 @@ -Index: nbd-3.10/nbd-server.c +Index: nbd-3.11/nbd-server.c =================================================================== ---- nbd-3.10.orig/nbd-server.c -+++ nbd-3.10/nbd-server.c +--- nbd-3.11.orig/nbd-server.c ++++ nbd-3.11/nbd-server.c @@ -1525,6 +1525,7 @@ CLIENT* negotiate(int net, GArray* serve err_nonfatal("Session terminated by client"); return NULL;
participants (1)
-
root@hilbert.suse.de