GNU bug report logs -
#27986
26.0.50; `rename-file' can rename files without confirmation
Previous Next
Reported by: Philipp <p.stephani2 <at> gmail.com>
Date: Sun, 6 Aug 2017 15:41:02 UTC
Severity: important
Tags: security
Found in version 26.0.50
Done: Paul Eggert <eggert <at> cs.ucla.edu>
Bug is archived. No further changes may be made.
Full log
Message #55 received at 27986 <at> debbugs.gnu.org (full text, mbox):
Eli Zaretskii wrote:
> Could you please take a step back and elaborate on the
> races and the security problems related to this, and why the change in
> the semantics you propose is the solution?
Currently (rename-file A B) requires at least two system calls to work: one to
test whether B is a directory, and the other to actually do the rename. This
leads to race conditions if other actors change the file system between the two
calls.
For example, suppose a victim is about to execute (rename-file "/tmp/foo"
"/tmp/bar" t), and suppose an attacker wants to destroy the victim's file
/home/victim/secret/foo. The attacker can do (make-symbolic-link
"/home/victim/secret" "/tmp/bar"), and this will cause the victim to lose all
the data in /home/victim/secret/bar even though the attacker is supposed to lack
access to anything under /home/victim/secret. I doubt whether this is the only
such scenario; it's just the first one that popped into my mind.
As icing on the cake, the current behavior of (rename-file A B) disagrees with
its documentation when B is an existing directory.
There is no good solution to this problem. All solutions are bad, in that either
they are not 100% backward compatible with existing behavior, or they continue
to encourage insecure Elisp code. The proposed patch attempts to choose the
least bad way forward, by making the default behavior more secure, at a
relatively minor cost in compatibility. Most uses of rename-file etc. won't care
about the change, and the ones that do care are likely to have security problems
anyway.
The proposed solution improves security, because a common pattern in Lisp code
when creating a file BAR "atomically" is to create and write a temporary file
FOO and then execute (rename-file FOO BAR). Currently, this approach can be
attacked in the way described when BAR's parent directory is /tmp or any similar
directory. With the proposed patch, this approach cannot be hijacked in this
way, because BAR will be a file name and not a directory name. That is, the call
to rename-file will specify whether the destination-directory semantics are
desired, rather than relying on the state of the filesystem to specify it. This
is more secure because the state of the filesystem is partially under control of
attackers.
This bug report was last modified 7 years and 257 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.