autofs-5.1.9 - fix tsv memory leak in set_tsd_user_vars()

From: Ian Kent <raven@themaw.net>

The thread specific data pointer is set in set_tsd_user_vars() without
first checking if one already exists. Since this function is called
multiple times the allocation gets leaked.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 CHANGELOG          |    1 +
 daemon/automount.c |    2 +-
 lib/mounts.c       |    9 ++++++++-
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 710e92a05..7859ca28c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -38,6 +38,7 @@
 - check map source in master_parse_entry().
 - fix possible memory leak in mnts_get_expire_list().
 - fix uninitialised list in struct master_mapent.
+- fix tsv memory leak in set_tsd_user_vars().
 
 02/11/2023 autofs-5.1.9
 - fix kernel mount status notification.
diff --git a/daemon/automount.c b/daemon/automount.c
index 8d7ad0c05..5e43455f2 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1941,7 +1941,7 @@ void *handle_mounts(void *arg)
 	return NULL;
 }
 
-static void key_thread_stdenv_vars_destroy(void *arg)
+void key_thread_stdenv_vars_destroy(void *arg)
 {
 	struct thread_stdenv_vars *tsv;
 
diff --git a/lib/mounts.c b/lib/mounts.c
index 6f9cc3109..1f0bea53b 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -52,6 +52,8 @@ static const char kver_options_template[]  = "fd=%d,pgrp=%u,minproto=3,maxproto=
 extern size_t detached_thread_stack_size;
 static size_t maxgrpbuf = 0;
 
+void key_thread_stdenv_vars_destroy(void *arg);
+
 #define EXT_MOUNTS_HASH_BITS	6
 
 struct ext_mount {
@@ -2421,12 +2423,17 @@ void set_tsd_user_vars(unsigned int logopt, uid_t uid, gid_t gid)
 	char *pw_tmp, *gr_tmp;
 	int status, tmplen, grplen;
 
+	tsv = pthread_getspecific(key_thread_stdenv_vars);
+	if (tsv) {
+		key_thread_stdenv_vars_destroy(tsv);
+		pthread_setspecific(key_thread_stdenv_vars, NULL);
+	}
+
 	/*
 	 * Setup thread specific data values for macro
 	 * substution in map entries during the mount.
 	 * Best effort only as it must go ahead.
 	 */
-
 	tsv = malloc(sizeof(struct thread_stdenv_vars));
 	if (!tsv) {
 		error(logopt, "failed alloc tsv storage");
