1
0
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:
Arjun Shankar
2024-10-18 16:03:25 +02:00
parent 81439a116c
commit 9f0d2c0ee6
5 changed files with 110 additions and 0 deletions

View File

@@ -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.