From b636f7fa1d8d4b0bf8e9e507d40588c23cb4f5c1 Mon Sep 17 00:00:00 2001
From: Fredrik Thulin <fredrik@thulin.net>
Date: Fri, 14 Dec 2012 15:52:45 +0100
Subject: [PATCH] Fix massive memory leak.

Commit 09669a08 introduced ds->cs.sock along side ds->socket.
The code that closed the socket only set ds->cs.sock to -1, so
the cleanup code (that looked at ds->socket) never realized it
should free the message buffers.

This commit removes ds->socket completely, and makes the
cleanup code look if ds->cs.sock is -1. Memory usage now stays
constant when looping 'pkcs11-tool --test --slot 0' at least.
---
 gck-rpc-dispatch.c | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/gck-rpc-dispatch.c b/gck-rpc-dispatch.c
index 8ba41cb..d694c52 100644
--- a/gck-rpc-dispatch.c
+++ b/gck-rpc-dispatch.c
@@ -72,7 +72,6 @@ typedef struct _DispatchState {
 	struct _DispatchState *next;
 	pthread_t thread;
 	CallState cs;
-	int socket;
 } DispatchState;
 
 /* A linked list of dispatcher threads */
@@ -884,11 +883,12 @@ static CK_RV rpc_C_Finalize(CallState * cs)
 		if (c->sock == cs->sock)
 			continue ;
 		if (c->req &&
-		    c->req->call_id == GCK_RPC_CALL_C_WaitForSlotEvent) {
-			gck_rpc_log("Sending interuption signal to %d\n",
-                                    ds->socket);
-			if (ds->socket)
-				shutdown(ds->socket, SHUT_RDWR);
+		    (c->req->call_id == GCK_RPC_CALL_C_WaitForSlotEvent)) {
+			gck_rpc_log("Sending interuption signal to %i\n",
+                                    c->sock);
+			if (c->sock != -1)
+				if (shutdown(c->sock, SHUT_RDWR) == 0)
+					c->sock = -1;
 			//pthread_kill(ds->thread, SIGINT);
 		}
 	}
@@ -2203,7 +2203,8 @@ void gck_rpc_layer_accept(void)
 	/* Cleanup any completed dispatch threads */
 	pthread_mutex_lock(&pkcs11_dispatchers_mutex);
 	for (here = &pkcs11_dispatchers, ds = *here; ds != NULL; ds = *here) {
-		if (ds->socket == -1) {
+		CallState *c = &ds->cs;
+		if (c && c->sock == -1) {
 			pthread_join(ds->thread, NULL);
 			*here = ds->next;
 			free(ds);
@@ -2227,7 +2228,6 @@ void gck_rpc_layer_accept(void)
 		return;
 	}
 
-	ds->socket = new_fd;
 	ds->cs.sock = new_fd;
         ds->cs.read = &read_all;
         ds->cs.write = &write_all;
@@ -2421,15 +2421,19 @@ void gck_rpc_layer_uninitialize(void)
 	/* Stop all of the dispatch threads */
 	pthread_mutex_lock(&pkcs11_dispatchers_mutex);
 	for (ds = pkcs11_dispatchers; ds; ds = next) {
+		CallState *c = &ds->cs;
 		next = ds->next;
 
 		/* Forcibly shutdown the connection */
-		if (ds->socket)
-			shutdown(ds->socket, SHUT_RDWR);
+		if (c && c->sock != -1)
+			if (shutdown(c->sock, SHUT_RDWR) == 0)
+				c->sock = -1;
+
 		pthread_join(ds->thread, NULL);
 
 		/* This is always closed by dispatch thread */
-		assert(ds->socket == -1);
+		if (c)
+			assert(c->sock == -1);
 		free(ds);
 	}
 	pthread_mutex_unlock(&pkcs11_dispatchers_mutex);
-- 
GitLab