From 4b18460bc6d69332c8d4da64bf6fcaceadbb4864 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 22 Dec 2017 16:02:23 +0100 Subject: [PATCH] archive/bz2: unlock the archive mutex and lock the file mutex Fixes deadlock because FileInputStream::Read() unlocks the mutex (which was not locked) and then locks it, keeping it locked. This can result in a deadlock. This happens because the archive and the file mutex are different. --- NEWS | 2 ++ src/archive/plugins/Bzip2ArchivePlugin.cxx | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 75889f7ed..394860cfc 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ ver 0.20.14 (not yet released) * database - simple: fix file corruption in the presence of mount points +* archive + - bz2: fix deadlock * fix Solaris build failure ver 0.20.13 (2017/12/18) diff --git a/src/archive/plugins/Bzip2ArchivePlugin.cxx b/src/archive/plugins/Bzip2ArchivePlugin.cxx index 3dc0b51c3..04597e2a2 100644 --- a/src/archive/plugins/Bzip2ArchivePlugin.cxx +++ b/src/archive/plugins/Bzip2ArchivePlugin.cxx @@ -162,7 +162,7 @@ Bzip2InputStream::FillBuffer() if (bzstream.avail_in > 0) return true; - size_t count = archive->istream->Read(buffer, sizeof(buffer)); + size_t count = archive->istream->LockRead(buffer, sizeof(buffer)); if (count == 0) return false; @@ -174,6 +174,8 @@ Bzip2InputStream::FillBuffer() size_t Bzip2InputStream::Read(void *ptr, size_t length) { + const ScopeUnlock unlock(mutex); + int bz_result; size_t nbytes = 0; @@ -224,4 +226,3 @@ const ArchivePlugin bz2_archive_plugin = { bz2_open, bz2_extensions, }; -