bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#25342: GNU coreutils: race condition in "ln -f source dest"


From: Mirsad Goran Todorovac
Subject: bug#25342: GNU coreutils: race condition in "ln -f source dest"
Date: Tue, 3 Jan 2017 03:32:57 +0000 (UTC)

Dear Sir,
It would suffice that:
linkat (AT_CWDFD, source, AT_CWDFD, dest, 0) == 0 || unlink (dest) == 0 && 
linkat (AT_CWDFD, source, AT_CWDFD, dest, 0) == 0;
be replaced with:
linkat (AT_CWDFD, source, AT_CWDFD, dest_tmp, 0) == 0 && renameat (AT_CWDFD, 
dest_tmp, AT_CWDFD, dest) == 0;
. This is exact equivalent of "ln -f A B.tmp; mv B.tmp B", true, as it had been 
cited, the rest is generating unique filename (MT safety is not yet done) and 
installing -o (--force-overwrite) option to command line.
Alternate behavior could be that default is to replace existing file atomically 
by default, and option is required or already existing to no-clobber.
If I do, for example:
# ln -f /etc/resolv.conf /etc/resolv.conf.orig# ln -f /etc/resolv.conf.ISP 
/etc/resolv.conf
there is a window in which ln comand can be preempted, and other processes 
trying i.e. gethostbyname() may or will fail (unless they have cached result).
This is equivalent to workaround with mv you provided above, but I think 
unlink() variant involves a race condition. And if I may assert - what is then 
forced? If desired behavior is to unlink() old existing target, then race 
condition involved is clearly a bug. IMHO.

I hope I am not too arrogant in these observations. And thank you very much for 
your time.

Regards,MT




 

    On Tuesday, January 3, 2017 2:07 AM, Paul Eggert <address@hidden> wrote:
 

 Although I like the idea of changing "ln -f A B" to do the equivalent of "ln 
-f 
A B.tmp; mv B.tmp B" when B already exists, I'm not sure I'd want to have a new 
option to restore the old behavior, as that would add complexity for little 
real 
benefit.

Also, this behavior shouldn't be limited to ln; it should also be done by cp -l.

   

reply via email to

[Prev in Thread] Current Thread [Next in Thread]