Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 130701790bf2d95e902edf16031ff596 > files > 180

autofs-5.0.1-0.rc2.164.el5_8.src.rpm

unchanged:
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -16,6 +16,7 @@
 - allow syntax "--timeout <secs>" for backward compatibility.
 - make masked_match independent of hostname for exports comparison.
 - fix file handle leak in nsswitch parser.
+- fix memory leak in mount and expire request processing.
 
 1/9/2006 autofs-5.0.1 rc2
 -------------------------
diff -u b/daemon/direct.c b/daemon/direct.c
--- b/daemon/direct.c
+++ b/daemon/direct.c
@@ -50,6 +50,9 @@
 pthread_key_t key_mnt_offset_params;
 pthread_once_t key_mnt_params_once = PTHREAD_ONCE_INIT;
 
+static pthread_mutex_t ma_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER;
+
 static void key_mnt_params_destroy(void *arg)
 {
 	struct mnt_params *mp;
@@ -797,6 +800,7 @@
 {
 	struct mnt_list *mnts = NULL, *next;
 	struct expire_args *ea;
+	struct expire_args ec;
 	struct autofs_point *ap;
 	struct mapent *me = NULL;
 	unsigned int now;
@@ -809,26 +813,21 @@
 	if (status)
 		fatal(status);
 
-	ap = ea->ap;
+	ap = ec.ap = ea->ap;
 	now = ea->when;
-	ea->status = -1;
+	ec.status = -1;
 
 	ea->signaled = 1;
 	status = pthread_cond_signal(&ea->cond);
-	if (status) {
-		error(ap->logopt, "failed to signal expire condition");
-		status = pthread_mutex_unlock(&ea->mutex);
-		if (status)
-			fatal(status);
-		pthread_exit(NULL);
-	}
-
-	pthread_cleanup_push(expire_cleanup, ea);
+	if (status)
+		fatal(status);
 
 	status = pthread_mutex_unlock(&ea->mutex);
 	if (status)
 		fatal(status);
 
+	pthread_cleanup_push(expire_cleanup, &ec);
+
 	left = 0;
 
 	/* Get a list of real mounts and expire them if possible */
@@ -883,7 +882,7 @@
 	}
 	pthread_cleanup_pop(1);
 
-	ea->status = left;
+	ec.status = left;
 
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
 	pthread_cleanup_pop(1);
@@ -892,24 +891,15 @@
 	return NULL;
 }
 
-void pending_cleanup(void *arg)
+static void pending_cond_destroy(void *arg)
 {
 	struct pending_args *mt;
 	int status;
 
 	mt = (struct pending_args *) arg;
-
-	status = pthread_mutex_unlock(&mt->mutex);
-	if (status)
-		fatal(status);
-
 	status = pthread_cond_destroy(&mt->cond);
 	if (status)
 		fatal(status);
-
-	status = pthread_mutex_destroy(&mt->mutex);
-	if (status)
-		fatal(status);
 }
 
 static void expire_send_fail(void *arg)
@@ -918,6 +908,19 @@
 	send_fail(mt->ioctlfd, mt->wait_queue_token);
 }
 
+static void free_pending_args(void *arg)
+{
+	struct pending_args *mt = arg;
+	free(mt);
+}
+
+static void expire_mutex_unlock(void *arg)
+{
+	int status = pthread_mutex_unlock(&ea_mutex);
+	if (status)
+		fatal(status);
+}
+
 static void *do_expire_direct(void *arg)
 {
 	struct pending_args *mt;
@@ -927,9 +930,7 @@
 
 	mt = (struct pending_args *) arg;
 
-	pthread_cleanup_push(expire_send_fail, mt);
-
-	status = pthread_mutex_lock(&mt->mutex);
+	status = pthread_mutex_lock(&ea_mutex);
 	if (status)
 		fatal(status);
 
@@ -940,9 +941,11 @@
 	if (status)
 		fatal(status);
 
-	status = pthread_mutex_unlock(&mt->mutex);
-	if (status)
-		fatal(status);
+	expire_mutex_unlock(NULL);
+
+	pthread_cleanup_push(free_pending_args, mt);
+	pthread_cleanup_push(pending_cond_destroy, mt);
+	pthread_cleanup_push(expire_send_fail, mt);
 
 	len = _strlen(mt->name, KEY_MAX_LEN);
 	if (!len) {
@@ -967,6 +970,9 @@
 	pthread_setcancelstate(state, NULL);
 
 	pthread_cleanup_pop(0);
+	pthread_cleanup_pop(1);
+	pthread_cleanup_pop(1);
+
 	return NULL;
 }
 
@@ -1027,15 +1033,11 @@
 		return 1;
 	}
 
-	status = pthread_mutex_init(&mt->mutex, NULL);
-	if (status)
-		fatal(status);
-
 	status = pthread_cond_init(&mt->cond, NULL);
 	if (status)
 		fatal(status);
 
-	status = pthread_mutex_lock(&mt->mutex);
+	status = pthread_mutex_lock(&ea_mutex);
 	if (status)
 		fatal(status);
 
@@ -1054,26 +1056,29 @@
 	status = pthread_create(&thid, &thread_attr, do_expire_direct, mt);
 	if (status) {
 		error(ap->logopt, "expire thread create failed");
-		free(mt);
 		send_fail(mt->ioctlfd, pkt->wait_queue_token);
 		cache_unlock(mc);
-		pending_cleanup(mt);
+		expire_mutex_unlock(NULL);
+		pending_cond_destroy(mt);
+		free_pending_args(mt);
 		pthread_setcancelstate(state, NULL);
 		return 1;
 	}
 
 	cache_unlock(mc);
-	pthread_cleanup_push(pending_cleanup, mt);
+
+	pthread_cleanup_push(expire_mutex_unlock, NULL);
 	pthread_setcancelstate(state, NULL);
 
 	mt->signaled = 0;
 	while (!mt->signaled) {
-		status = pthread_cond_wait(&mt->cond, &mt->mutex);
+		status = pthread_cond_wait(&mt->cond, &ea_mutex);
 		if (status)
 			fatal(status);
 	}
 
 	pthread_cleanup_pop(1);
+
 	return 0;
 }
 
@@ -1084,6 +1089,13 @@
 	close(mt->ioctlfd);
 }
 
+static void mount_mutex_unlock(void *arg)
+{
+	int status = pthread_mutex_unlock(&ma_mutex);
+	if (status)
+		fatal(status);
+}
+
 static void *do_mount_direct(void *arg)
 {
 	struct pending_args *mt;
@@ -1102,7 +1114,7 @@
 
 	mt = (struct pending_args *) arg;
 
-	status = pthread_mutex_lock(&mt->mutex);
+	status = pthread_mutex_lock(&ma_mutex);
 	if (status)
 		fatal(status);
 
@@ -1113,11 +1125,12 @@
 	if (status)
 		fatal(status);
 
-	status = pthread_mutex_unlock(&mt->mutex);
-	if (status)
-		fatal(status);
+	mount_mutex_unlock(NULL);
 
+	pthread_cleanup_push(free_pending_args, mt);
+	pthread_cleanup_push(pending_cond_destroy, mt);
 	pthread_cleanup_push(mount_send_fail, mt);
+
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
 
 	status = fstat(mt->ioctlfd, &st);
@@ -1271,6 +1284,9 @@
 	pthread_setcancelstate(state, NULL);
 
 	pthread_cleanup_pop(0);
+	pthread_cleanup_pop(1);
+	pthread_cleanup_pop(1);
+
 	return NULL;
 }
 
@@ -1353,23 +1369,19 @@
 		pthread_setcancelstate(state, NULL);
 		return 1;
 	}
-
-	status = pthread_mutex_init(&mt->mutex, NULL);
-	if (status)
-		fatal(status);
+	memset(mt, 0, sizeof(struct pending_args));
 
 	status = pthread_cond_init(&mt->cond, NULL);
 	if (status)
 		fatal(status);
 
-	status = pthread_mutex_lock(&mt->mutex);
+	status = pthread_mutex_lock(&ma_mutex);
 	if (status)
 		fatal(status);
 
 	mt->ap = ap;
 	mt->ioctlfd = ioctlfd;
 	mt->mc = mc;
-	/* TODO: check length here */
 	strcpy(mt->name, me->key);
 	mt->dev = me->dev;
 	mt->type = NFY_MOUNT;
@@ -1380,22 +1392,23 @@
 	status = pthread_create(&thid, &thread_attr, do_mount_direct, mt);
 	if (status) {
 		error(ap->logopt, "missing mount thread create failed");
-		free(mt);
 		send_fail(ioctlfd, pkt->wait_queue_token);
 		close(ioctlfd);
 		cache_unlock(mc);
-		pending_cleanup(mt);
+		mount_mutex_unlock(NULL);
+		pending_cond_destroy(mt);
+		free_pending_args(mt);
 		pthread_setcancelstate(state, NULL);
 		return 1;
 	}
 
 	cache_unlock(mc);
-	pthread_cleanup_push(pending_cleanup, mt);
+	pthread_cleanup_push(mount_mutex_unlock, NULL);
 	pthread_setcancelstate(state, NULL);
 
 	mt->signaled = 0;
 	while (!mt->signaled) {
-		status = pthread_cond_wait(&mt->cond, &mt->mutex);
+		status = pthread_cond_wait(&mt->cond, &ma_mutex);
 		if (status)
 			fatal(status);
 	}
diff -u b/daemon/indirect.c b/daemon/indirect.c
--- b/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -40,6 +40,9 @@
 
 extern pthread_attr_t thread_attr;
 
+static pthread_mutex_t ma_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER;
+
 static int autofs_init_indirect(struct autofs_point *ap)
 {
 	int pipefd[2];
@@ -419,6 +422,7 @@
 	struct mapent *me = NULL;
 	struct mnt_list *mnts = NULL, *next;
 	struct expire_args *ea;
+	struct expire_args ec;
 	unsigned int now;
 	int offsets, submnts, count;
 	int ioctlfd, cur_state;
@@ -430,26 +434,21 @@
 	if (status)
 		fatal(status);
 
-	ap = ea->ap;
+	ap = ec.ap = ea->ap;
 	now = ea->when;
-	ea->status = -1;
+	ec.status = -1;
 
 	ea->signaled = 1;
 	status = pthread_cond_signal(&ea->cond);
-	if (status) {
-		error(ap->logopt, "failed to signal expire condition");
-		status = pthread_mutex_unlock(&ea->mutex);
-		if (status)
-			fatal(status);
-		pthread_exit(NULL);
-	}
-
-	pthread_cleanup_push(expire_cleanup, ea);
+	if (status)
+		fatal(status);
 
 	status = pthread_mutex_unlock(&ea->mutex);
 	if (status)
 		fatal(status);
 
+	pthread_cleanup_push(expire_cleanup, &ec);
+
 	left = 0;
 
 	/* Get a list of real mounts and expire them if possible */
@@ -559,7 +558,7 @@
 			msg("mount still busy %s", ap->path);
 	}
 
-	ea->status = left;
+	ec.status = left;
 
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
 	pthread_cleanup_pop(1);
@@ -568,8 +567,16 @@
 	return NULL;
 }
 
-/* See direct.c */
-extern void pending_cleanup(void *);
+static void pending_cond_destroy(void *arg)
+{
+	struct pending_args *mt;
+	int status;
+
+	mt = (struct pending_args *) arg;
+	status = pthread_cond_destroy(&mt->cond);
+	if (status)
+		fatal(status);
+}
 
 static void expire_send_fail(void *arg)
 {
@@ -577,6 +584,19 @@
 	send_fail(mt->ap->ioctlfd, mt->wait_queue_token);
 }
 
+static void free_pending_args(void *arg)
+{
+	struct pending_args *mt = arg;
+	free(mt);
+}
+
+static void expire_mutex_unlock(void *arg)
+{
+	int status = pthread_mutex_unlock(&ea_mutex);
+	if (status)
+		fatal(status);
+}
+
 static void *do_expire_indirect(void *arg)
 {
 	struct pending_args *mt;
@@ -585,7 +605,7 @@
 
 	mt = (struct pending_args *) arg;
 
-	status = pthread_mutex_lock(&mt->mutex);
+	status = pthread_mutex_lock(&ea_mutex);
 	if (status)
 		fatal(status);
 
@@ -596,10 +616,10 @@
 	if (status)
 		fatal(status);
 
-	status = pthread_mutex_unlock(&mt->mutex);
-	if (status)
-		fatal(status);
+	expire_mutex_unlock(NULL);
 
+	pthread_cleanup_push(free_pending_args, mt);
+	pthread_cleanup_push(pending_cond_destroy, mt);
 	pthread_cleanup_push(expire_send_fail, mt);
 
 	status = do_expire(mt->ap, mt->name, mt->len);
@@ -611,6 +631,8 @@
 	pthread_setcancelstate(state, NULL);
 
 	pthread_cleanup_pop(0);
+	pthread_cleanup_pop(1);
+	pthread_cleanup_pop(1);
 
 	return NULL;
 }
@@ -636,15 +658,11 @@
 		return 1;
 	}
 
-	status = pthread_mutex_init(&mt->mutex, NULL);
-	if (status)
-		fatal(status);
-
 	status = pthread_cond_init(&mt->cond, NULL);
 	if (status)
 		fatal(status);
 
-	status = pthread_mutex_lock(&mt->mutex);
+	status = pthread_mutex_lock(&ea_mutex);
 	if (status)
 		fatal(status);
 
@@ -658,18 +676,19 @@
 	if (status) {
 		error(ap->logopt, "expire thread create failed");
 		send_fail(ap->ioctlfd, pkt->wait_queue_token);
-		free(mt);
-		pending_cleanup(mt);
+		expire_mutex_unlock(NULL);
+		pending_cond_destroy(mt);
+		free_pending_args(mt);
 		pthread_setcancelstate(state, NULL);
 		return 1;
 	}
 
-	pthread_cleanup_push(pending_cleanup, mt);
+	pthread_cleanup_push(expire_mutex_unlock, NULL);
 	pthread_setcancelstate(state, NULL);
 
 	mt->signaled = 0;
 	while (!mt->signaled) {
-		status = pthread_cond_wait(&mt->cond, &mt->mutex);
+		status = pthread_cond_wait(&mt->cond, &ea_mutex);
 		if (status)
 			fatal(status);
 	}
@@ -685,6 +704,13 @@
 	send_fail(mt->ap->ioctlfd, mt->wait_queue_token);
 }
 
+static void mount_mutex_unlock(void *arg)
+{
+	int status = pthread_mutex_unlock(&ma_mutex);
+	if (status)
+		fatal(status);
+}
+
 static void *do_mount_indirect(void *arg)
 {
 	struct pending_args *mt;
@@ -703,7 +729,7 @@
 
 	mt = (struct pending_args *) arg;
 
-	status = pthread_mutex_lock(&mt->mutex);
+	status = pthread_mutex_lock(&ma_mutex);
 	if (status)
 		fatal(status);
 
@@ -715,16 +741,17 @@
 	if (status)
 		fatal(status);
 
-	status = pthread_mutex_unlock(&mt->mutex);
-	if (status)
-		fatal(status);
+	mount_mutex_unlock(NULL);
+
+	pthread_cleanup_push(free_pending_args, mt);
+	pthread_cleanup_push(pending_cond_destroy, mt);
+	pthread_cleanup_push(mount_send_fail, mt);
 
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
 
 	len = ncat_path(buf, sizeof(buf), ap->path, mt->name, mt->len);
 	if (!len) {
 		crit(ap->logopt, "path to be mounted is to long");
-		send_fail(ap->ioctlfd, mt->wait_queue_token);
 		pthread_setcancelstate(state, NULL);
 		pthread_exit(NULL);
 	}
@@ -733,12 +760,10 @@
 	if (status != -1 && !(S_ISDIR(st.st_mode) && st.st_dev == mt->dev)) {
 		error(ap->logopt,
 		      "indirect trigger not valid or already mounted %s", buf);
-		send_fail(ap->ioctlfd, mt->wait_queue_token);
 		pthread_setcancelstate(state, NULL);
 		pthread_exit(NULL);
 	}
 
-	pthread_cleanup_push(mount_send_fail, mt);
 	pthread_setcancelstate(state, NULL);
 
 	msg("attempting to mount entry %s", buf);
@@ -862,6 +887,9 @@
 	pthread_setcancelstate(state, NULL);
 
 	pthread_cleanup_pop(0);
+	pthread_cleanup_pop(1);
+	pthread_cleanup_pop(1);
+
 	return NULL;
 }
 
@@ -894,16 +922,13 @@
 		pthread_setcancelstate(state, NULL);
 		return 1;
 	}
-
-	status = pthread_mutex_init(&mt->mutex, NULL);
-	if (status)
-		fatal(status);
+	memset(mt, 0, sizeof(struct pending_args));
 
 	status = pthread_cond_init(&mt->cond, NULL);
 	if (status)
 		fatal(status);
 
-	status = pthread_mutex_lock(&mt->mutex);
+	status = pthread_mutex_lock(&ma_mutex);
 	if (status)
 		fatal(status);
 
@@ -920,18 +945,19 @@
 	if (status) {
 		error(ap->logopt, "expire thread create failed");
 		send_fail(ap->ioctlfd, pkt->wait_queue_token);
-		free(mt);
-		pending_cleanup(mt);
+		mount_mutex_unlock(NULL);
+		pending_cond_destroy(mt);
+		free_pending_args(mt);
 		pthread_setcancelstate(state, NULL);
 		return 1;
 	}
 
-	pthread_cleanup_push(pending_cleanup, mt);
+	pthread_cleanup_push(mount_mutex_unlock, NULL);
 	pthread_setcancelstate(state, NULL);
 
 	mt->signaled = 0;
 	while (!mt->signaled) {
-		status = pthread_cond_wait(&mt->cond, &mt->mutex);
+		status = pthread_cond_wait(&mt->cond, &ma_mutex);
 		if (status)
 			fatal(status);
 	}
unchanged:
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -94,14 +94,14 @@ void nextstate(int statefd, enum states 
 void expire_cleanup(void *arg)
 {
 	pthread_t thid = pthread_self();
-	struct expire_args *ea;
+	struct expire_args *ec;
 	struct autofs_point *ap;
 	int statefd, success;
 	enum states next = ST_INVAL;
 
-	ea = (struct expire_args *) arg;
-	ap = ea->ap;
-	success = ea->status;
+	ec = (struct expire_args *) arg;
+	ap = ec->ap;
+	success = ec->status;
 
 	state_mutex_lock(ap);
 
@@ -190,8 +190,6 @@ #endif
 
 	state_mutex_unlock(ap);
 
-	free(ea);
-
 	return;
 }
 
@@ -242,6 +240,8 @@ void expire_proc_cleanup(void *arg)
 	if (status)
 		fatal(status);
 
+	free(ea);
+
 	return;
 }