mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-15 01:43:40 -06:00
Fix flaw in thread creation APIs
The arguments passed to the thread function must be allocated on the heap, rather than the stack, since it is possible for the spawning thread to continue before the new thread runs at all. In such a case, it is possible that the area of stack where the thread args were stored is overwritten. * src/util/threads-pthread.c, src/util/threads-win32.c: Allocate thread arguments on the heap
This commit is contained in:
parent
33e38e7710
commit
9c65609247
@ -26,6 +26,8 @@
|
||||
# include <sys/syscall.h>
|
||||
#endif
|
||||
|
||||
#include "memory.h"
|
||||
|
||||
|
||||
/* Nothing special required for pthreads */
|
||||
int virThreadInitialize(void)
|
||||
@ -143,6 +145,7 @@ static void *virThreadHelper(void *data)
|
||||
{
|
||||
struct virThreadArgs *args = data;
|
||||
args->func(args->opaque);
|
||||
VIR_FREE(args);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -151,17 +154,25 @@ int virThreadCreate(virThreadPtr thread,
|
||||
virThreadFunc func,
|
||||
void *opaque)
|
||||
{
|
||||
struct virThreadArgs args = { func, opaque };
|
||||
struct virThreadArgs *args;
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
if (VIR_ALLOC(args) < 0)
|
||||
return -1;
|
||||
|
||||
args->func = func;
|
||||
args->opaque = opaque;
|
||||
|
||||
if (!joinable)
|
||||
pthread_attr_setdetachstate(&attr, 1);
|
||||
|
||||
int ret = pthread_create(&thread->thread, &attr, virThreadHelper, &args);
|
||||
int ret = pthread_create(&thread->thread, &attr, virThreadHelper, args);
|
||||
if (ret != 0) {
|
||||
VIR_FREE(args);
|
||||
errno = ret;
|
||||
return -1;
|
||||
}
|
||||
/* New thread owns 'args' in success case, so don't free */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -230,6 +230,8 @@ static void virThreadHelperDaemon(void *data)
|
||||
|
||||
TlsSetValue(selfkey, NULL);
|
||||
CloseHandle(self.thread);
|
||||
|
||||
VIR_FREE(args);
|
||||
}
|
||||
|
||||
static unsigned int __stdcall virThreadHelperJoinable(void *data)
|
||||
@ -249,6 +251,8 @@ static unsigned int __stdcall virThreadHelperJoinable(void *data)
|
||||
|
||||
TlsSetValue(selfkey, NULL);
|
||||
CloseHandle(self.thread);
|
||||
|
||||
VIR_FREE(args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -257,17 +261,24 @@ int virThreadCreate(virThreadPtr thread,
|
||||
virThreadFunc func,
|
||||
void *opaque)
|
||||
{
|
||||
struct virThreadArgs args = { func, opaque };
|
||||
struct virThreadArgs *args;
|
||||
|
||||
if (VIR_ALLOC(args) < 0)
|
||||
return -1;
|
||||
|
||||
args->func = func;
|
||||
args->opaque = opaque;
|
||||
|
||||
thread->joinable = joinable;
|
||||
if (joinable) {
|
||||
thread->thread = (HANDLE)_beginthreadex(NULL, 0,
|
||||
virThreadHelperJoinable,
|
||||
&args, 0, NULL);
|
||||
args, 0, NULL);
|
||||
if (thread->thread == 0)
|
||||
return -1;
|
||||
} else {
|
||||
thread->thread = (HANDLE)_beginthread(virThreadHelperDaemon,
|
||||
0, &args);
|
||||
0, args);
|
||||
if (thread->thread == (HANDLE)-1L)
|
||||
return -1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user