mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-08 17:42:12 +03:00
libio: Fix a deadlock after fork in popen
popen modifies its file handler book-keeping under a lock that wasn't being taken during fork. This meant that a concurrent popen and fork could end up copying the lock in a "locked" state into the fork child, where subsequently calling popen would lead to a deadlock due to the already (spuriously) held lock. This commit fixes the deadlock by appropriately taking the lock before fork, and releasing/resetting it in the parent/child after the fork. A new test for concurrent popen and fork is also added. It consistently hangs (and therefore fails via timeout) without the fix applied. Reviewed-by: Florian Weimer <fweimer@redhat.com>
This commit is contained in:
@@ -57,6 +57,26 @@ unlock (void *not_used)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* These lock/unlock/resetlock functions are used during fork. */
|
||||
|
||||
void
|
||||
_IO_proc_file_chain_lock (void)
|
||||
{
|
||||
_IO_lock_lock (proc_file_chain_lock);
|
||||
}
|
||||
|
||||
void
|
||||
_IO_proc_file_chain_unlock (void)
|
||||
{
|
||||
_IO_lock_unlock (proc_file_chain_lock);
|
||||
}
|
||||
|
||||
void
|
||||
_IO_proc_file_chain_resetlock (void)
|
||||
{
|
||||
_IO_lock_init (proc_file_chain_lock);
|
||||
}
|
||||
|
||||
/* POSIX states popen shall ensure that any streams from previous popen()
|
||||
calls that remain open in the parent process should be closed in the new
|
||||
child process.
|
||||
|
Reference in New Issue
Block a user