- 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

OBS-URL: https://build.opensuse.org/package/show/network:utilities/nbd?expand=0&rev=33
This commit is contained in:
Martin Pluskal 2015-05-28 11:42:20 +00:00 committed by Git OBS Bridge
parent 6e1eb1c315
commit 6a043af7c6
8 changed files with 26 additions and 198 deletions

View File

@ -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';

View File

@ -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.

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6fc53a7a67ab6c786586ee155b76b502d3ff14f4233e9077957968b3bf3847ce
size 461508

3
nbd-3.11.tar.xz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:14420f74cb16dc609a9302ed1efd653064bed7a8357e9d73daabc33608e3f2a0
size 451992

View File

@ -1,3 +1,13 @@
-------------------------------------------------------------------
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
-------------------------------------------------------------------
Mon May 11 08:13:48 UTC 2015 - mpluskal@suse.com

View File

@ -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 @@ Patch2: nbd-2.9.25-close.diff
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 @@ the connection closes.
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%build
export CFLAGS="%{optflags} -fstack-protector -fno-strict-aliasing"

View File

@ -1,181 +0,0 @@
Index: nbd-3.10/nbd-server.c
===================================================================
--- nbd-3.10.orig/nbd-server.c
+++ nbd-3.10/nbd-server.c
@@ -168,6 +168,16 @@ char default_authname[] = SYSCONFDIR "/n
#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 @@ GArray* parse_cfile(gchar* f, struct gen
}
/**
- * 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 @@ void killchild(gpointer key, gpointer va
}
/**
- * 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;
}
/**
@@ -2066,9 +2066,12 @@ spawn_child()
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;
@@ -2262,9 +2265,12 @@ handle_oldstyle_connection(GArray *const
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);
@@ -2368,6 +2374,8 @@ void serveloop(GArray* servers) {
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
@@ -2390,7 +2398,56 @@ void serveloop(GArray* servers) {
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
@@ -2425,8 +2482,7 @@ void serveloop(GArray* servers) {
}
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);

View File

@ -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;