[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-167-g4319a8f

edwin edwin at 77e5149b-7576-45b1-b177-96237e5ba77b
Fri Jun 12 19:11:58 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 5411bff4776c92815a0971b9c7d1d8075248eec5
Author: edwin <edwin at 77e5149b-7576-45b1-b177-96237e5ba77b>
Date:   Wed May 6 07:56:28 2009 +0000

    Fix 60 byte/STREAM command memory leak on FreeBSD. (bb #1567,
    thanks to Jay Deiman <jay*splitstreams.com> and Chris Mikkelson <cmikk*qwest.net> for tracking down the leak!).
    
    git-svn-id: http://svn.clamav.net/svn/clamav-devel/trunk@5061 77e5149b-7576-45b1-b177-96237e5ba77b

diff --git a/ChangeLog b/ChangeLog
index 0f051cb..fde1760 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Wed May  6 10:40:19 EEST 2009 (edwin)
+-------------------------------------
+ * clamd/others.c, clamd/others.h, clamd/server-th.c,
+ clamd/session.c, clamd/thrmgr.c: Fix 60 byte/STREAM command memory
+ leak on FreeBSD. (bb #1567, thanks to Jay Deiman
+ <jay*splitstreams.com> and Chris Mikkelson <cmikk*qwest.net> for
+ tracking down the leak!).
+
 Tue May  5 16:31:14 CEST 2009 (tk)
 ----------------------------------
  * shared: fix compiler warnings
diff --git a/clamd/others.c b/clamd/others.c
index bf1c848..2c70de8 100644
--- a/clamd/others.c
+++ b/clamd/others.c
@@ -215,15 +215,13 @@ static int realloc_polldata(struct fd_data *data)
 int poll_fd(int fd, int timeout_sec, int check_signals)
 {
     int ret;
-    struct fd_data fds = FDS_INIT;
+    struct fd_data fds = FDS_INIT(NULL);
 
     if (fds_add(&fds, fd, 1, timeout_sec) == -1)
 	return -1;
-    pthread_mutex_lock(&fds.buf_mutex);
     do {
 	ret = fds_poll_recv(&fds, timeout_sec, check_signals);
     } while (ret == -1 && errno == EINTR);
-    pthread_mutex_unlock(&fds.buf_mutex);
     fds_free(&fds);
     return ret;
 }
@@ -396,10 +394,22 @@ int fds_add(struct fd_data *data, int fd, int listen_only, int timeout)
     return 0;
 }
 
+static inline void fds_lock(struct fd_data *data)
+{
+    if (data->buf_mutex)
+	pthread_mutex_lock(data->buf_mutex);
+}
+
+static inline void fds_unlock(struct fd_data *data)
+{
+    if (data->buf_mutex)
+	pthread_mutex_unlock(data->buf_mutex);
+}
+
 void fds_remove(struct fd_data *data, int fd)
 {
     size_t i;
-    pthread_mutex_lock(&data->buf_mutex);
+    fds_lock(data);
     if (data->buf) {
 	for (i=0;i<data->nfds;i++) {
 	    if (data->buf[i].fd == fd) {
@@ -408,7 +418,7 @@ void fds_remove(struct fd_data *data, int fd)
 	    }
 	}
     }
-    pthread_mutex_unlock(&data->buf_mutex);
+    fds_unlock(data);
 }
 
 #ifndef	C_WINDOWS
@@ -421,7 +431,7 @@ void fds_remove(struct fd_data *data, int fd)
  * timeout is specified in seconds, if check_signals is non-zero, then
  * poll_recv_fds() will return upon receipt of a signal, even if no data
  * is received on any of the sockets.
- * Must be called with buf_mutex held.
+ * Must be called with buf_mutex lock held.
  */
 /* TODO: handle ReadTimeout */
 int fds_poll_recv(struct fd_data *data, int timeout, int check_signals)
@@ -488,9 +498,9 @@ int fds_poll_recv(struct fd_data *data, int timeout, int check_signals)
     do {
 	int n = data->nfds;
 
-	pthread_mutex_unlock(&data->buf_mutex);
+	fds_unlock(data);
 	retval = poll(data->poll_data, n, timeout);
-	pthread_mutex_lock(&data->buf_mutex);
+	fds_lock(data);
 
 	if (retval > 0) {
 	    fdsok = 0;
@@ -567,9 +577,9 @@ int fds_poll_recv(struct fd_data *data, int timeout, int check_signals)
 	tv.tv_sec = timeout;
 	tv.tv_usec = 0;
 
-	pthread_mutex_unlock(&data->buf_mutex);
+	fds_unlock(data);
 	retval = select(maxfd+1, &rfds, NULL, NULL, timeout >= 0 ? &tv : NULL);
-	pthread_mutex_lock(&data->buf_mutex);
+	fds_lock(data);
 	if (retval > 0) {
 	    fdsok = data->nfds;
 	    for (i=0; i < data->nfds; i++) {
@@ -637,7 +647,7 @@ int fds_poll_recv(struct fd_data *data, int timeout, int check_signals)
 void fds_free(struct fd_data *data)
 {
     unsigned i;
-    pthread_mutex_lock(&data->buf_mutex);
+    fds_lock(data);
     for (i=0;i < data->nfds;i++) {
 	if (data->buf[i].buffer) {
 	    free(data->buf[i].buffer);
@@ -651,5 +661,5 @@ void fds_free(struct fd_data *data)
 #endif
     data->buf = NULL;
     data->nfds = 0;
-    pthread_mutex_unlock(&data->buf_mutex);
+    fds_unlock(data);
 }
diff --git a/clamd/others.h b/clamd/others.h
index cea69c3..ddd9b25 100644
--- a/clamd/others.h
+++ b/clamd/others.h
@@ -58,7 +58,7 @@ struct fd_buf {
 };
 
 struct fd_data {
-    pthread_mutex_t buf_mutex; /* protects buf and nfds */
+    pthread_mutex_t *buf_mutex; /* protects buf and nfds */
     struct fd_buf *buf;
     size_t nfds;
 #ifdef HAVE_POLL
@@ -68,9 +68,9 @@ struct fd_data {
 };
 
 #ifdef HAVE_POLL
-#define FDS_INIT { PTHREAD_MUTEX_INITIALIZER, NULL, 0, NULL, 0}
+#define FDS_INIT(mutex) { (mutex), NULL, 0, NULL, 0}
 #else
-#define FDS_INIT { PTHREAD_MUTEX_INITIALIZER, NULL, 0}
+#define FDS_INIT(mutex) { (mutex), NULL, 0}
 #endif
 
 int poll_fd(int fd, int timeout_sec, int check_signals);
diff --git a/clamd/server-th.c b/clamd/server-th.c
index 5d28927..59d62e0 100644
--- a/clamd/server-th.c
+++ b/clamd/server-th.c
@@ -313,7 +313,7 @@ struct acceptdata {
     int syncpipe_wake_accept[2];
 };
 
-#define ACCEPTDATA_INIT { FDS_INIT, FDS_INIT, PTHREAD_COND_INITIALIZER, 0, 0, {-1, -1}, {-1, -1}}
+#define ACCEPTDATA_INIT(mutex1, mutex2) { FDS_INIT(mutex1), FDS_INIT(mutex2), PTHREAD_COND_INITIALIZER, 0, 0, {-1, -1}, {-1, -1}}
 
 static void *acceptloop_th(void *arg)
 {
@@ -325,7 +325,7 @@ static void *acceptloop_th(void *arg)
     int max_queue = data->max_queue;
     int commandtimeout = data->commandtimeout;
 
-    pthread_mutex_lock(&fds->buf_mutex);
+    pthread_mutex_lock(fds->buf_mutex);
     for (;;) {
 	/* Block waiting for data to become available for reading */
 	int new_sd = fds_poll_recv(fds, -1, 0);
@@ -367,17 +367,17 @@ static void *acceptloop_th(void *arg)
 
 	    /* don't accept unlimited number of connections, or
 	     * we'll run out of file descriptors */
-	    pthread_mutex_lock(&recv_fds->buf_mutex);
-	    while (recv_fds->nfds > max_queue) {
+	    pthread_mutex_lock(recv_fds->buf_mutex);
+	    while (recv_fds->nfds > (unsigned)max_queue) {
 		pthread_mutex_lock(&exit_mutex);
 		if(progexit) {
 		    pthread_mutex_unlock(&exit_mutex);
 		    break;
 		}
 		pthread_mutex_unlock(&exit_mutex);
-		pthread_cond_wait(&data->cond_nfds, &recv_fds->buf_mutex);
+		pthread_cond_wait(&data->cond_nfds, recv_fds->buf_mutex);
 	    }
-	    pthread_mutex_unlock(&recv_fds->buf_mutex);
+	    pthread_mutex_unlock(recv_fds->buf_mutex);
 
 	    pthread_mutex_lock(&exit_mutex);
 	    if(progexit) {
@@ -406,9 +406,9 @@ static void *acceptloop_th(void *arg)
 		logg("^Nonblocking sockets not available!\n");
 #endif
 		logg("$Got new connection, FD %d\n", new_sd);
-		pthread_mutex_lock(&recv_fds->buf_mutex);
+		pthread_mutex_lock(recv_fds->buf_mutex);
 		ret = fds_add(recv_fds, new_sd, 0, commandtimeout);
-		pthread_mutex_unlock(&recv_fds->buf_mutex);
+		pthread_mutex_unlock(recv_fds->buf_mutex);
 
 		if (ret == -1) {
 		    logg("!fds_add failed\n");
@@ -443,7 +443,7 @@ static void *acceptloop_th(void *arg)
 	}
 	pthread_mutex_unlock(&exit_mutex);
     }
-    pthread_mutex_unlock(&fds->buf_mutex);
+    pthread_mutex_unlock(fds->buf_mutex);
 
     for (i=0;i < fds->nfds; i++) {
 	if (fds->buf[i].fd == -1)
@@ -699,7 +699,9 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
 	unsigned long long val;
 	size_t i, j, rr_last = 0;
 	pthread_t accept_th;
-	struct acceptdata acceptdata = ACCEPTDATA_INIT;
+	pthread_mutex_t fds_mutex = PTHREAD_MUTEX_INITIALIZER;
+	pthread_mutex_t recvfds_mutex = PTHREAD_MUTEX_INITIALIZER;
+	struct acceptdata acceptdata = ACCEPTDATA_INIT(&fds_mutex, &recvfds_mutex);
 	struct fd_data *fds = &acceptdata.recv_fds;
 	time_t start_time, current_time;
 	unsigned int selfchk;
@@ -1077,12 +1079,12 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
     for(;;) {
 	int new_sd;
 	/* Block waiting for connection on any of the sockets */
-	pthread_mutex_lock(&fds->buf_mutex);
+	pthread_mutex_lock(fds->buf_mutex);
 	fds_cleanup(fds);
 	/* signal that we can accept more connections */
-	if (fds->nfds <= max_queue)
+	if (fds->nfds <= (unsigned)max_queue)
 	    pthread_cond_signal(&acceptdata.cond_nfds);
-	new_sd = fds_poll_recv(fds, selfchk ? selfchk : -1, 1);
+	new_sd = fds_poll_recv(fds, selfchk ? (int)selfchk : -1, 1);
 
 	if (!fds->nfds) {
 	    /* at least the dummy/sync pipe should have remained */
@@ -1090,7 +1092,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
 	    pthread_mutex_lock(&exit_mutex);
 	    progexit = 1;
 	    pthread_mutex_unlock(&exit_mutex);
-	    pthread_mutex_unlock(&fds->buf_mutex);
+	    pthread_mutex_unlock(fds->buf_mutex);
 	    break;
 	}
 
@@ -1146,9 +1148,6 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
 		   buf->mode != MODE_WAITANCILL) {
 		client_conn_t conn;
 		const unsigned char *cmd = NULL;
-		size_t cmdlen = 0;
-		char term = '\n';
-		int oldstyle = 0;
 		int rc;
 		/* New data available to read on socket. */
 
@@ -1210,13 +1209,13 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
 		buf->fd = -1;
 	    }
 	}
-	pthread_mutex_unlock(&fds->buf_mutex);
+	pthread_mutex_unlock(fds->buf_mutex);
 
 	/* handle progexit */
 	pthread_mutex_lock(&exit_mutex);
 	if (progexit) {
 	    pthread_mutex_unlock(&exit_mutex);
-	    pthread_mutex_lock(&fds->buf_mutex);
+	    pthread_mutex_lock(fds->buf_mutex);
 	    for (i=0;i < fds->nfds; i++) {
 		if (fds->buf[i].fd == -1)
 		    continue;
@@ -1228,7 +1227,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
 		    fds->buf[i].fd = -1;
 		}
 	    }
-	    pthread_mutex_unlock(&fds->buf_mutex);
+	    pthread_mutex_unlock(fds->buf_mutex);
 	    break;
 	}
 	pthread_mutex_unlock(&exit_mutex);
diff --git a/clamd/session.c b/clamd/session.c
index f20cc14..3e2d623 100644
--- a/clamd/session.c
+++ b/clamd/session.c
@@ -228,6 +228,8 @@ int command(client_conn_t *conn, int *virus)
 	    thrmgr_setactivetask(NULL, "MULTISCAN");
 	    type = TYPE_MULTISCAN;
 	    scandata.group = group = thrmgr_group_new();
+	    if (!group)
+		return CL_EMEM;
 	    break;
 	case COMMAND_MULTISCANFILE:
 	    thrmgr_setactivetask(NULL, "MULTISCANFILE");
diff --git a/clamd/thrmgr.c b/clamd/thrmgr.c
index 1ba2aa8..af4a56c 100644
--- a/clamd/thrmgr.c
+++ b/clamd/thrmgr.c
@@ -770,6 +770,8 @@ int thrmgr_group_finished(jobgroup_t *group, enum thrmgr_exit exitc)
     pthread_mutex_unlock(&group->mutex);
     if (ret) {
 	logg("$THRMGR: group_finished: freeing %p\n", group);
+	pthread_mutex_destroy(&group->mutex);
+	pthread_cond_destroy(&group->only);
 	free(group);
     }
     return ret;
@@ -805,16 +807,26 @@ void thrmgr_group_waitforall(jobgroup_t *group, unsigned *ok, unsigned *error, u
     }
 }
 
-#define JOBGROUP_INITIALIZER  { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 1, 0, 0, 0, 0 };
 jobgroup_t *thrmgr_group_new(void)
 {
     jobgroup_t *group;
-    jobgroup_t dummy = JOBGROUP_INITIALIZER;
 
     group = malloc(sizeof(*group));
     if (!group)
 	return NULL;
-    memcpy(group, &dummy, sizeof(dummy));
+    group->jobs = 1;
+    group->exit_ok = group->exit_error = group->exit_total = group->force_exit = 0;
+    if (pthread_mutex_init(&group->mutex, NULL)) {
+	logg("^Failed to initialize group mutex");
+	free(group);
+	return NULL;
+    }
+    if (pthread_cond_init(&group->only, NULL)) {
+	logg("^Failed to initialize group cond");
+	pthread_mutex_destroy(&group->mutex);
+	free(group);
+	return NULL;
+    }
     logg("$THRMGR: new group: %p\n", group);
     return group;
 }

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list