[Bug 45935] Race condition in implementation of MoveFile, MoveFileEx, MoveFileWithProgress

wine-bugs at winehq.org wine-bugs at winehq.org
Sun Oct 7 19:30:47 CDT 2018


https://bugs.winehq.org/show_bug.cgi?id=45935

--- Comment #8 from Joshua <joshudson at gmail.com> ---
I don't know enough about the internals of Wine to know if you could take an
exclusive lock on a file name that corresponds to a non-extant file. I do know
that there's no way that Copy+Delete will ever work. The race condition on that
one is stupid huge, as the reader could pick up a partial or empty file. The
original author didn't do the rename() thing but just kept on opening files
until he got a name that didn't exist. We found that one years ago because it
was really broken.

The obvious ways of taking a name lock don't work because this MoveFile call is
cross-process.

This appears to be a solution:

if (0 >= (h = open(newfile, O_EXCL|O_CREAT, 0)) {
    close(h);
    ret = rename(oldfile, newfile);
}

In fact it is not. The race is very much present in the reader process opening
the junk file. In theory if you could take a mandatory lock on open() this
would work:

if (0 >= (h = open(newfile, O_EXCL|O_CREAT|O_MANDLOCK, 04000)) {
    retn = rename(oldfile, newfile);
    close(h);
}

But you can't. The following works but is a crawling horror:

if (!(mkdir(newfile)) {
    ret = rename(oldfile, newfile);
}

Basically I shudder at this one because while it *works*, the quantum directory
just seems like it's asking for something else to fall down on it.

You could try the quantum symlink to nowhere trick

if (!symlink("\001\001\001\001", newfile)) {
    ret = rename(oldfile, newfile);
}

but that won't work on FAT, which is how I got here in the first place.

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.



More information about the wine-bugs mailing list