diff options
-rw-r--r-- | nptl/ChangeLog | 12 | ||||
-rw-r--r-- | nptl/pthreadP.h | 7 | ||||
-rw-r--r-- | nptl/pthread_cancel.c | 8 | ||||
-rw-r--r-- | nptl/pthread_detach.c | 8 | ||||
-rw-r--r-- | nptl/pthread_getschedparam.c | 24 | ||||
-rw-r--r-- | nptl/pthread_join.c | 2 | ||||
-rw-r--r-- | nptl/pthread_setschedparam.c | 26 | ||||
-rw-r--r-- | nptl/pthread_timedjoin.c | 3 | ||||
-rw-r--r-- | nptl/sysdeps/pthread/pthread_getcpuclockid.c | 21 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/pthread_kill.c | 10 |
10 files changed, 85 insertions, 36 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 2c5c338231..05bab0b525 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,5 +1,17 @@ 2003-02-21 Ulrich Drepper <drepper@redhat.com> + * pthreadP.h: Define INVALID_TD_P and INVALID_NOT_TERMINATED_TD_P. + * pthread_cancel.c: Use INVALID_TD_P. + * pthread_detach.c: Likewise. + * pthread_getschedparam.c: Likewise. + * pthread_setschedparam.c: Likewise. + * sysdeps/pthread/pthread_getcpuclockid.c: Likewise. + * sysdeps/unix/sysv/linux/pthread_kill.c: Likewise. + * pthread_join.c: Use INVALID_NOT_TERMINATED_TD_P. + * pthread_timedjoin.c: Likewise. + + * tst-basic7.c: Include <signal.h>. + * pthread_join.c (pthread_join): Limited checking for invalid descriptors. * pthread_timedjoin.c (pthread_timedjoin_np): Likewise. diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h index 11f7ede32f..e88b9591e4 100644 --- a/nptl/pthreadP.h +++ b/nptl/pthreadP.h @@ -70,8 +70,15 @@ extern int __pthread_debug attribute_hidden; /** For now disable debugging support. */ #if 0 # define DEBUGGING_P __builtin_expect (__pthread_debug, 0) +# define INVALID_TD_P(pd) (DEBUGGING_P && __find_in_stack_list (pd) == NULL) +# define INVALID_NOT_TERMINATED_TD_P(pd) INVALID_TD_P (pd) #else # define DEBUGGING_P 0 +/* Simplified test. This will not catch all invalid descriptors but + is better than nothing. And if the test triggers the thread + descriptor is guaranteed to be invalid. */ +# define INVALID_TD_P(pd) __builtin_expect ((pd)->tid <= 0, 0) +# define INVALID_NOT_TERMINATED_TD_P(pd) __builtin_expect ((pd)->tid < 0, 0) #endif diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c index 153cb198d8..805e74f2b1 100644 --- a/nptl/pthread_cancel.c +++ b/nptl/pthread_cancel.c @@ -17,6 +17,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <errno.h> #include <signal.h> #include "pthreadP.h" #include "atomic.h" @@ -27,8 +28,13 @@ pthread_cancel (th) pthread_t th; { volatile struct pthread *pd = (volatile struct pthread *) th; - int result = 0; + /* Make sure the descriptor is valid. */ + if (INVALID_TD_P (pd)) + /* Not a valid thread handle. */ + return ESRCH; + + int result = 0; while (1) { int oldval = pd->cancelhandling; diff --git a/nptl/pthread_detach.c b/nptl/pthread_detach.c index 2ba9f4913d..ff58e3bde5 100644 --- a/nptl/pthread_detach.c +++ b/nptl/pthread_detach.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -27,6 +27,12 @@ pthread_detach (th) pthread_t th; { struct pthread *pd = (struct pthread *) th; + + /* Make sure the descriptor is valid. */ + if (INVALID_TD_P (pd)) + /* Not a valid thread handle. */ + return ESRCH; + int result = 0; /* Mark the thread as detached. */ diff --git a/nptl/pthread_getschedparam.c b/nptl/pthread_getschedparam.c index 72b366d8cf..d9d6cb43b0 100644 --- a/nptl/pthread_getschedparam.c +++ b/nptl/pthread_getschedparam.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -17,33 +17,39 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <errno.h> #include <string.h> #include "pthreadP.h" #include <lowlevellock.h> int -__pthread_getschedparam (thread_id, policy, param) - pthread_t thread_id; +__pthread_getschedparam (threadid, policy, param) + pthread_t threadid; int *policy; struct sched_param *param; { - struct pthread *thread = (struct pthread *) thread_id; + struct pthread *pd = (struct pthread *) threadid; + + /* Make sure the descriptor is valid. */ + if (INVALID_TD_P (pd)) + /* Not a valid thread handle. */ + return ESRCH; /* We have to handle cancellation in the following code since we are locking another threads desriptor. */ - pthread_cleanup_push ((void (*) (void *)) lll_unlock_wake_cb, &thread->lock); + pthread_cleanup_push ((void (*) (void *)) lll_unlock_wake_cb, &pd->lock); - lll_lock (thread->lock); + lll_lock (pd->lock); /* The library is responsible for maintaining the values at all times. If the user uses a interface other than pthread_setschedparam to modify the scheduler setting it is not the library's problem. */ - *policy = thread->schedpolicy; - memcpy (param, &thread->schedparam, sizeof (struct sched_param)); + *policy = pd->schedpolicy; + memcpy (param, &pd->schedparam, sizeof (struct sched_param)); - lll_unlock (thread->lock); + lll_unlock (pd->lock); pthread_cleanup_pop (0); diff --git a/nptl/pthread_join.c b/nptl/pthread_join.c index 84f993c700..5a0ec95722 100644 --- a/nptl/pthread_join.c +++ b/nptl/pthread_join.c @@ -40,7 +40,7 @@ pthread_join (threadid, thread_return) struct pthread *pd = (struct pthread *) threadid; /* Make sure the descriptor is valid. */ - if ((DEBUGGING_P && __find_in_stack_list (pd) == NULL) || pd->tid <= 0) + if (INVALID_NOT_TERMINATED_TD_P (pd)) /* Not a valid thread handle. */ return ESRCH; diff --git a/nptl/pthread_setschedparam.c b/nptl/pthread_setschedparam.c index cdba80cf07..3084836ad8 100644 --- a/nptl/pthread_setschedparam.c +++ b/nptl/pthread_setschedparam.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -25,33 +25,39 @@ int -__pthread_setschedparam (thread_id, policy, param) - pthread_t thread_id; +__pthread_setschedparam (threadid, policy, param) + pthread_t threadid; int policy; const struct sched_param *param; { - struct pthread *thread = (struct pthread *) thread_id; + struct pthread *pd = (struct pthread *) threadid; + + /* Make sure the descriptor is valid. */ + if (INVALID_TD_P (pd)) + /* Not a valid thread handle. */ + return ESRCH; + int result = 0; /* We have to handle cancellation in the following code since we are locking another threads desriptor. */ - pthread_cleanup_push ((void (*) (void *)) lll_unlock_wake_cb, &thread->lock); + pthread_cleanup_push ((void (*) (void *)) lll_unlock_wake_cb, &pd->lock); - lll_lock (thread->lock); + lll_lock (pd->lock); /* Try to set the scheduler information. */ - if (__builtin_expect (__sched_setscheduler (thread->tid, policy, + if (__builtin_expect (__sched_setscheduler (pd->tid, policy, param) == -1, 0)) result = errno; else { /* We succeeded changing the kernel information. Reflect this change in the thread descriptor. */ - thread->schedpolicy = policy; - memcpy (&thread->schedparam, param, sizeof (struct sched_param)); + pd->schedpolicy = policy; + memcpy (&pd->schedparam, param, sizeof (struct sched_param)); } - lll_unlock (thread->lock); + lll_unlock (pd->lock); pthread_cleanup_pop (0); diff --git a/nptl/pthread_timedjoin.c b/nptl/pthread_timedjoin.c index 0883f94f60..c83c0ef953 100644 --- a/nptl/pthread_timedjoin.c +++ b/nptl/pthread_timedjoin.c @@ -19,7 +19,6 @@ #include <errno.h> #include <stdlib.h> - #include "atomic.h" #include "pthreadP.h" @@ -42,7 +41,7 @@ pthread_timedjoin_np (threadid, thread_return, abstime) int result; /* Make sure the descriptor is valid. */ - if ((DEBUGGING_P && __find_in_stack_list (pd) == NULL) || pd->tid <= 0) + if (INVALID_NOT_TERMINATED_TD_P (pd)) /* Not a valid thread handle. */ return ESRCH; diff --git a/nptl/sysdeps/pthread/pthread_getcpuclockid.c b/nptl/sysdeps/pthread/pthread_getcpuclockid.c index 62761f9d7a..6386dc4dc0 100644 --- a/nptl/sysdeps/pthread/pthread_getcpuclockid.c +++ b/nptl/sysdeps/pthread/pthread_getcpuclockid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,23 +17,30 @@ Boston, MA 02111-1307, USA. */ #include <errno.h> -#include <pthread.h> +#include <pthreadP.h> #include <sys/time.h> #include <tls.h> int -pthread_getcpuclockid (thread_id, clock_id) - pthread_t thread_id; - clockid_t *clock_id; +pthread_getcpuclockid (threadid, clockid) + pthread_t threadid; + clockid_t *clockid; { + struct pthread *pd = (struct pthread *) threadid; + + /* Make sure the descriptor is valid. */ + if (INVALID_TD_P (pd)) + /* Not a valid thread handle. */ + return ESRCH; + /* We don't allow any process ID but our own. */ - if ((struct pthread *) thread_id != THREAD_SELF) + if (pd != THREAD_SELF) return EPERM; #ifdef CLOCK_THREAD_CPUTIME_ID /* Store the number. */ - *clock_id = CLOCK_THREAD_CPUTIME_ID; + *clockid = CLOCK_THREAD_CPUTIME_ID; return 0; #else diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_kill.c b/nptl/sysdeps/unix/sysv/linux/pthread_kill.c index ca6dfd887a..2caa72882f 100644 --- a/nptl/sysdeps/unix/sysv/linux/pthread_kill.c +++ b/nptl/sysdeps/unix/sysv/linux/pthread_kill.c @@ -31,14 +31,14 @@ __pthread_kill (threadid, signo) { struct pthread *pd = (struct pthread *) threadid; + /* Make sure the descriptor is valid. */ + if (INVALID_TD_P (pd)) + /* Not a valid thread handle. */ + return ESRCH; + /* We have a special syscall to do the work. */ INTERNAL_SYSCALL_DECL (err); - /* The kernel returns EINVAL for PIDs <= 0. This is not nice since - the user would expect ESRCH. Correct it here. */ - if (pd->tid <= 0) - return ESRCH; - int val = INTERNAL_SYSCALL (tkill, err, 2, pd->tid, signo); return (INTERNAL_SYSCALL_ERROR_P (val, err) |