Bug 18504

Summary: pthread_set_name_np leaks memory
Product: Base System Reporter: James FitzGibbon <james>
Component: miscAssignee: Jason Evans <jasone>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 3.2-RELEASE   
Hardware: Any   
OS: Any   

Description James FitzGibbon 2000-05-11 18:10:00 UTC
struct pthread contains a member variable "char *name", which is used to
store the name of the thread.  pthread_set_name_np is used to set this
member variable.  There are several problems:

- pthread_create does not set the member to a known valid state (NULL)
- pthread_set_name_np does not check if the member is NULL before assigning
  the return value of strdup to it.
- the garbage collector thread (lib/libc_r/uthread/uthread_gc.c) does not
  free the memory used by the member, if any.

Fix: The following patch addresses the above three issues.



The patch is relative to RELENG_4, but should apply to -current as well.

After the standard wait period, a MFC to RELENG_4 (and RELENG_3 if possible)
would be appreciated.--hmbR5YOaY454Nao2Ru9Med7JC2jni8hKz6DHK8Yp3hGBaHqT
Content-Type: text/plain; name="file.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="file.diff"

diff -ru /usr/src/lib/libc_r/uthread/uthread_create.c uthread/uthread_create.c
--- /usr/src/lib/libc_r/uthread/uthread_create.c	Thu Mar 23 02:06:40 2000
+++ uthread/uthread_create.c	Thu May 11 12:47:49 2000
@@ -164,6 +164,7 @@
 			new_thread->slice_usec = -1;
 			new_thread->sig_saved = 0;
 			new_thread->stack = stack;
+			new_thread->name = NULL;
 			new_thread->start_routine = start_routine;
 			new_thread->arg = arg;
 
diff -ru /usr/src/lib/libc_r/uthread/uthread_gc.c uthread/uthread_gc.c
--- /usr/src/lib/libc_r/uthread/uthread_gc.c	Tue Dec 28 13:13:02 1999
+++ uthread/uthread_gc.c	Thu May 11 12:53:15 2000
@@ -243,6 +243,13 @@
 			free(p_stack);
 		if (pthread_cln != NULL)
 			/*
+			   Free the memory allocated for the thread
+			   name, if any
+			/*
+			if( pthread_cln.name != NULL ) {
+				free(pthread_cln.name);
+			}
+			/*
 			 * Free the memory allocated for the thread
 			 * structure.
 			 */
diff -ru /usr/src/lib/libc_r/uthread/uthread_info.c uthread/uthread_info.c
--- /usr/src/lib/libc_r/uthread/uthread_info.c	Wed Sep 29 11:18:38 1999
+++ uthread/uthread_info.c	Thu May 11 12:48:32 2000
@@ -305,6 +305,10 @@
 {
 	/* Check if the caller has specified a valid thread: */
 	if (thread != NULL && thread->magic == PTHREAD_MAGIC)
+		/* Free the existing name, if any */
+		if( thread->name != NULL ) {
+			free(thread_name);
+		}
 		thread->name = strdup(name);
 	return;
 }
How-To-Repeat: 
Call pthread_set_name_np multiple times.  The program will leak as many
bytes as are passed as to pthread_set_name_np.
Comment 1 Jason Evans freebsd_committer freebsd_triage 2000-05-12 08:21:11 UTC
Responsible Changed
From-To: freebsd-bugs->jasone

Over to maintainer. 

Comment 2 Jeroen Ruigrok/Asmodai 2000-05-13 12:50:31 UTC
Jason, can you please look at this patch?

-On [20000511 20:02], James FitzGibbon (james@targetnet.com) wrote:
>
>>Fix:
>
>The following patch addresses the above three issues.
>
>diff -ru /usr/src/lib/libc_r/uthread/uthread_create.c uthread/uthread_create.c
>--- /usr/src/lib/libc_r/uthread/uthread_create.c	Thu Mar 23 02:06:40 2000
>+++ uthread/uthread_create.c	Thu May 11 12:47:49 2000
>@@ -164,6 +164,7 @@
> 			new_thread->slice_usec = -1;
> 			new_thread->sig_saved = 0;
> 			new_thread->stack = stack;
>+			new_thread->name = NULL;
> 			new_thread->start_routine = start_routine;
> 			new_thread->arg = arg;
> 
>diff -ru /usr/src/lib/libc_r/uthread/uthread_gc.c uthread/uthread_gc.c
>--- /usr/src/lib/libc_r/uthread/uthread_gc.c	Tue Dec 28 13:13:02 1999
>+++ uthread/uthread_gc.c	Thu May 11 12:53:15 2000
>@@ -243,6 +243,13 @@
> 			free(p_stack);
> 		if (pthread_cln != NULL)
> 			/*
>+			   Free the memory allocated for the thread
>+			   name, if any
>+			/*
>+			if( pthread_cln.name != NULL ) {
>+				free(pthread_cln.name);
>+			}
>+			/*
> 			 * Free the memory allocated for the thread
> 			 * structure.
> 			 */
>diff -ru /usr/src/lib/libc_r/uthread/uthread_info.c uthread/uthread_info.c
>--- /usr/src/lib/libc_r/uthread/uthread_info.c	Wed Sep 29 11:18:38 1999
>+++ uthread/uthread_info.c	Thu May 11 12:48:32 2000
>@@ -305,6 +305,10 @@
> {
> 	/* Check if the caller has specified a valid thread: */
> 	if (thread != NULL && thread->magic == PTHREAD_MAGIC)
>+		/* Free the existing name, if any */
>+		if( thread->name != NULL ) {
>+			free(thread_name);
>+		}
> 		thread->name = strdup(name);
> 	return;
> }
>
>The patch is relative to RELENG_4, but should apply to -current as well.

I don't think this should be a problem.

>After the standard wait period, a MFC to RELENG_4 (and RELENG_3 if possible)
>would be appreciated.

Of course.

-- 
Jeroen Ruigrok vd Werven/Asmodai    asmodai@[wxs.nl|bart.nl|freebsd.org]
Documentation nutter/C-rated Coder BSD: Technical excellence at its best  
The BSD Programmer's Documentation Project <http://home.wxs.nl/~asmodai>
I could shed anoter million tears, a million breaths, a million names
but only one Truth to face...
Comment 3 Jeroen Ruigrok/Asmodai 2000-05-13 12:51:56 UTC
Oh damn.

Just found the reply. =\

Sorry for the duplication.  Nice to see you on the case already. ;)

Mea culpa,

-- 
Jeroen Ruigrok vd Werven/Asmodai    asmodai@[wxs.nl|bart.nl|freebsd.org]
Documentation nutter/C-rated Coder BSD: Technical excellence at its best  
The BSD Programmer's Documentation Project <http://home.wxs.nl/~asmodai>
A rose is a rose is a rose is a rose...
Comment 4 Jason Evans freebsd_committer freebsd_triage 2000-05-16 23:20:45 UTC
State Changed
From-To: open->feedback

Fix checked into -current.  Waiting to MFC. 
Comment 5 Jason Evans freebsd_committer freebsd_triage 2000-07-17 19:41:15 UTC
State Changed
From-To: feedback->closed

Patch applied (with minor changes) to HEAD and RELENG_4.