Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 893b4547bb5f5eb61d2f3af4281e5a38 > files > 13

cman-2.0.115-96.el5_8.1.src.rpm

commit 587c2f737a9a0b2f2339b10651a998ddae48f892
Author: Fabio M. Di Nitto <fdinitto@redhat.com>
Date:   Fri Aug 12 16:00:00 2011 +0200

    cman: do not free shutdown connection till the last message is sent
    
    the shutdown connection was incorrectly freed too early in the process
    and re-used again after free, sometimes sending random bytes to fd 0 (syslog).
    
    Resolves: rhbz#727215
    
    Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
    Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>

diff --git a/cman/daemon/cnxman-private.h b/cman/daemon/cnxman-private.h
index c823a70..f12bca9 100644
--- a/cman/daemon/cnxman-private.h
+++ b/cman/daemon/cnxman-private.h
@@ -133,7 +133,7 @@ struct connection
 	uint32_t   confchg;     /* Registered for confchg */
 	struct list write_msgs; /* Queued messages to go to data clients */
 	uint32_t    num_write_msgs; /* Count of messages */
-	struct connection *next;
+	uint32_t    shutdown_con;
 	struct list list;       /* when on the client_list */
 };
 
diff --git a/cman/daemon/commands.c b/cman/daemon/commands.c
index 6c91d7a..6e0160b 100644
--- a/cman/daemon/commands.c
+++ b/cman/daemon/commands.c
@@ -944,6 +944,7 @@ static int do_cmd_try_shutdown(struct connection *con, char *cmdbuf)
 	shutdown_yes = 0;
 	shutdown_no = 0;
 	shutdown_expected = num_listeners();
+	shutdown_con->shutdown_con = 1;
 
 	/* If no-one is listening for events then we can just go down now */
 	if (shutdown_expected == 0) {
diff --git a/cman/daemon/daemon.c b/cman/daemon/daemon.c
index 08aeb80..c1250e7 100644
--- a/cman/daemon/daemon.c
+++ b/cman/daemon/daemon.c
@@ -116,6 +116,12 @@ static void remove_client(poll_handle handle, struct connection *con)
 	struct queued_reply *qm;
 	int msgs=0;
 
+	if (con->shutdown_con) {
+		P_DAEMON("Delay removal of shutdown connection\n");
+		con->shutdown_con = 0;
+		return;
+	}
+
 	poll_dispatch_delete(handle, con->fd);
 	close(con->fd);
 	if (con->type == CON_CLIENT)
@@ -340,6 +346,7 @@ static int process_rendezvous(poll_handle handle, int fd, int revent, void *data
 		newcon->port = 0;
 		newcon->events = 0;
 		newcon->num_write_msgs = 0;
+		newcon->shutdown_con = 0;
 		list_init(&newcon->write_msgs);
 		fcntl(client_fd, F_SETFL, fcntl(client_fd, F_GETFL, 0) | O_NONBLOCK);