[PATCH RFC] libio: Fix deadlock between freopen and fclose [BZ #24963]

谢宜生(毅晟) yisheng.xys@alibaba-inc.com
Sat Sep 21 03:22:00 GMT 2019


we find a deadlock between fclose and freopen as following:
CPU0                                          CPU1
freopen                                       fclose
  ->_IO_acquire_lock (fp)                         ->_IO_un_link
  ->_IO_file_close_it                              ->_IO_lock_lock(list_all_lock)
    ->_IO_un_link
      ->_IO_lock_lock (list_all_lock)<-wait here
                                                   ->_IO_flockfile((_IO_FILE *) fp); <-- wait here

As Carlos pointed that this maybe the bug of in _IO_new_fclose, which
can be fixed by locking fp first, then with fp acquired lock the whole
list.

Signed-off-by: Yisheng Xie <yisheng.xys@alibaba-inc.com>
---
 libio/iofclose.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libio/iofclose.c b/libio/iofclose.c
index 398b86d597..fe262cf6aa 100644
--- a/libio/iofclose.c
+++ b/libio/iofclose.c
@@ -44,11 +44,11 @@ _IO_new_fclose (FILE *fp)
     return _IO_old_fclose (fp);
 #endif

+  _IO_acquire_lock (fp);
   /* First unlink the stream.  */
   if (fp->_flags & _IO_IS_FILEBUF)
     _IO_un_link ((struct _IO_FILE_plus *) fp);

-  _IO_acquire_lock (fp);
   if (fp->_flags & _IO_IS_FILEBUF)
     status = _IO_file_close_it (fp);
   else
--
2.23.0



More information about the Libc-alpha mailing list