This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix possible deadlock in stdio locking code


On Tue, Oct 18, 2011 at 04:58:59PM +0200, Andreas Schwab wrote:
> Siddhesh Poyarekar <spoyarek@redhat.com> writes:
> 
> > 1) thread A pushes the cleanup callback flush_cleanup using
> >    _IO_cleanup_region_start_noarg()
> >
> > 2) Some other thread calls pthread_cancel on thread A before it gets
> >    to call _IO_lock_lock(list_all_lock)
> 
> That pthread_cancel call will have no effect until the next cancellation
> point.
> 

I have come up with a reproducer for this (at the end of this
email). I have verified that the fix in my original submission:

http://sourceware.org/ml/libc-alpha/2011-10/msg00036.html

fixes this problem. It cannot be fixed within _IO_flush_all_lockp() in
libio/genops.c due to the way pthread_cleanup_push and
pthread_cleanup_pop have been implemented.


--
Siddhesh

The reproducer:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

pthread_mutex_t mutex;

void *do_fork(void *foo)
{
	while(1) {
		int child = fork();

		if (child == 0)
			exit(0);

		waitpid(-1, NULL, 0);
		sleep(1);
	}
}

void *do_io(void *foo)
{
	FILE *f = fopen("/tmp/foo", "w+");
	if (f)
		fprintf(f, "hellllllllllllllllllllllloooooooooooooo");
	fcloseall();
}

int main(int argc, char **argv)
{
	pthread_t fork_thr;

	pthread_create(&fork_thr, NULL, do_fork, NULL);
	pthread_mutex_init(&mutex, NULL);

	while (1) {
		pthread_t io_thr;
		pthread_create(&io_thr, NULL, do_io, NULL);
		pthread_cancel(io_thr);
		pthread_join(io_thr, NULL);
	}
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]