]> git.ipfire.org Git - thirdparty/coreutils.git/commit
ln: avoid directory hard-link races
authorPaul Eggert <eggert@cs.ucla.edu>
Fri, 19 Oct 2018 19:19:43 +0000 (12:19 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Fri, 19 Oct 2018 19:38:34 +0000 (12:38 -0700)
commit571f63f5010b047a8a3250304053f05949faded4
treea207753907f2ad471fb6078a8970f987eeebc0f1
parentcbc427485e8c202b8aeae567f99c4a080a55adac
ln: avoid directory hard-link races

Previously, 'ln A B' did 'stat("B"), lstat("A"), link("A","B")'
where the stat and lstat were necessary to avoid hard-linking
directories on systems that can hard-link directories.
Now, in situations that prohibit hard links to directories,
'ln A B' merely does 'link("A","B")'.  The new behavior
avoids some races and should be more efficient.
This patch was inspired by Bug#10020, which was about 'ln'.
* bootstrap.conf (gnulib_modules): Add unlinkdir.
* src/force-link.c (force_linkat, force_symlinkat): New arg for
error number of previous try.  Return error number, 0, or -1 if
error, success, or success after removal.  All callers changed.
* src/ln.c: Include priv-set.h, unlinkdir.h.
(beware_hard_dir_link): New static var.
(errnoize, atomic_link): New functions.
(target_directory_operand): Use errnoize for simplicity.
(do_link): New arg for error number of previous try.  All callers
changed.  Do each link atomically if possible.
(main): Do -r check earlier.  Remove linkdir privileges so we can
use a single linkat/symlinkat instead of a racy substitute for the
common case of 'ln A B' and 'ln -s A B'.  Set beware_hard_dir_link
to disable this optimization.
NEWS
bootstrap.conf
src/copy.c
src/force-link.c
src/force-link.h
src/ln.c