llfio icon indicating copy to clipboard operation
llfio copied to clipboard

Address or document racy nature of Windows unlink() emulation

Open rcombs opened this issue 6 years ago • 1 comments

Context: https://github.com/ned14/llfio/blob/fd12a60d26c80d93185ff0e0da1efa4ddbbf3863/include/llfio/v2.0/detail/impl/windows/fs_handle.ipp#L243-L279

When the win_disable_unlink_emulation flag is not set, on Windows prior to Windows 10 1709, llfio will handle an unlink() via 3 separate syscalls: one to rename the file to something random, one to mark the file as hidden, and one to mark it as deleted.

This results in two windows during which an application or system crash could result in inconsistent (and potentially very harmful) results. If the crash occurs between the rename and the mark-as-hidden, then the user could possibly see the file and delete it later (though they're less likely to if it's in some obscure application-data directory), but if it occurs between the mark-as-hidden and the delete, it may be fairly difficult to remove the file, which could be problematic, especially if it's large.

Personally, I don't think the mark-as-hidden is a good choice here, particularly since the randomized name is briefly visible anyway. I'm not sure if the period between the rename and the mark-as-deleted is possible to address short of not making unlink emulation the default, but if it's not going to be addressed, then the documentation should indicate that this is a possible failure mode, and how developers should attempt to recover from it if possible (i.e. by searching application-data directories where they regularly delete files for entries with .deleted extensions and removing them).

rcombs avatar Dec 29 '18 04:12 rcombs

Thing is, I didn't used to mark as hidden before setting delete on close, and then I got complaints about files named hex.deleted being all over the place. Another alternative is to rename files into a temporary directory before setting delete on close, but there is no guarantee that a suitable temporary directory exists on the same volume.

None of the options available here are good. I think the current choice is the least worst on older windows given the competing factors. The current behavior is already documented in the flags, but I think you're right it's not documented in the unlink API docs currently. So I'll leave this open to remind me to fix that when I get back to Europe next week. Thanks for reporting this issue!

ned14 avatar Dec 29 '18 04:12 ned14