Boost C++ Libraries: Ticket #11166: boost::filesystem::remove is racy https://svn.boost.org/trac10/ticket/11166 <p> As the attached program demonstrates (typically in way under 1s here), if two threads or processes attempt to remove the same file, one of the removers can get an exception because 'no such file or directory', even though not existing at the time of the call is *not* an error condition for remove. </p> <p> I have only verified this bug to exist in 1.49 and 1.53, but I glanced at github's boostorg/filesystem/blob/master/src/operations.cpp and it looks like the same problem is likely to exist--namely, that remove_file can fail because somebody else removed the file we were about to remove, after we verified that the file existed via query_file_type. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/11166 Trac 1.4.3 Jeff Epler <jepler@…> Fri, 03 Apr 2015 20:05:21 GMT attachment set https://svn.boost.org/trac10/ticket/11166 https://svn.boost.org/trac10/ticket/11166 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">fsremoverace.cc</span> </li> </ul> <p> demonstrate race in boost::filesystem::remove </p> Ticket Jeff Epler <jepler@…> Fri, 03 Apr 2015 20:08:57 GMT <link>https://svn.boost.org/trac10/ticket/11166#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11166#comment:1</guid> <description> <p> It's also interesting to contemplate that the change might not be [directory/file/symlink] -&gt; [nonexistent], but could also be [directory/file/symlink] -&gt; [directory/file/symlink]. </p> </description> <category>Ticket</category> </item> <item> <author>Jeff Epler <jepler@…></author> <pubDate>Mon, 06 Apr 2015 14:50:08 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/11166 https://svn.boost.org/trac10/ticket/11166 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">boost-11166-fs-remove-race.patch</span> </li> </ul> <p> Proposed fix </p> Ticket Jeff Epler <jepler@…> Mon, 06 Apr 2015 14:58:27 GMT <link>https://svn.boost.org/trac10/ticket/11166#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11166#comment:2</guid> <description> <p> The proposed patch fixes the file -&gt; nonexistent and directory -&gt; nonexistent cases. The others are not as important for our use case, but for example (errno == EISDIR) would be an appropriate check after unlink() for the file -&gt; directory case. Lightly tested via my test case on Linux and Windows. </p> </description> <category>Ticket</category> </item> <item> <author>Jeff Epler <jepler@…></author> <pubDate>Mon, 06 Apr 2015 21:00:11 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11166#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11166#comment:3</guid> <description> <p> This bug may be easier to hit than I first supposed. We have now received some information that this may be exacerbated by the "SMB2 Client Redirector cache" (Windows, Vista and later), which by default will cache positive existence of a file for 10 seconds, making a nice big window for trouble as long as two machines sharing the same Windows share are involved. A similar design choice on Unix with NFS (attribute caching) probably creates nice big windows there too. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Beman Dawes</dc:creator> <pubDate>Tue, 01 Sep 2015 15:34:56 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/11166#comment:4 https://svn.boost.org/trac10/ticket/11166#comment:4 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> A change similar to the suggested patch has been applied. It covers the same set of error codes used elsewhere to identify the general "file not found" case. </p> <p> Please note that this change mitigates but does not totally eliminate the chance of external file system races. </p> <p> It does not protect against multi-threading data races. "Data races are bad", to quote Howard Hinnant and a bunch of other experts. For rationale, see <a class="ext-link" href="https://software.intel.com/en-us/blogs/2013/01/06/benign-data-races-what-could-possibly-go-wrong"><span class="icon">​</span>https://software.intel.com/en-us/blogs/2013/01/06/benign-data-races-what-could-possibly-go-wrong</a> </p> <p> The test program provide has both a file system race and a data race, so it always fails for me (four core CPU, Windows 10, 64-bit system, VC++ 2015, Boost 1.59) because of the data race regardless of anything done to mitigate the file system race. </p> <p> Thanks for the report, example program, and patch, </p> <p> --Beman </p> <p> </p> Ticket anonymous Tue, 01 Sep 2015 16:24:38 GMT <link>https://svn.boost.org/trac10/ticket/11166#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11166#comment:5</guid> <description> <p> I appreciate your comments about the safety of threaded code. I provided a threaded program for ease of reproduction, and may have not adequately observed threaded programming safeguards. </p> <p> In our use case, the real how-to-reproduce involves multiple processes, often on different systems with a networked file system, concurrently creating and deleting files. </p> <p> Since these activities are human driven, we can't enforce that two users don't both delete the same item from the filesystem at close enough to the same time that the cached existence in the SMB2 Client Redirector Cache doesn't trigger this issue. </p> </description> <category>Ticket</category> </item> </channel> </rss>