Skip to content

Commit 9d4daf2

Browse files
committed
Remove hard links from env::current_exe security example
The security example shows that `env::current_exe` will return the path used when the program was started. This is not really surprising considering how hard links work: after `ln foo bar`, the two files are _equivalent_. It is _not_ the case that `bar` is a “link” to `foo`, nor is `foo` a link to `bar`. They are simply two names for the same underlying data. The security vulnerability linked to seems to be different: there an attacker would start a SUID binary from a directory under the control of the attacker. The binary would respawn itself by executing the program found at `/proc/self/exe` (which the attacker can control). This is a real problem. In my opinion, the example given here doesn’t really show the same problem, it just shows a misunderstanding of what hard links are. I looked through the history a bit and found that the example was introduced in #33526. That PR actually has two commits, and the first (8478d48dad949b3b1374569a5391089a49094eeb) explains the race condition at the root of the linked security vulnerability. The second commit proceeds to replace the explanation with the example we have today. This commit reverts most of the second commit from #33526.
1 parent 88eccd9 commit 9d4daf2

File tree

1 file changed

+17
-30
lines changed

1 file changed

+17
-30
lines changed

std/src/env.rs

+17-30
Original file line numberDiff line numberDiff line change
@@ -644,36 +644,23 @@ pub fn temp_dir() -> PathBuf {
644644
///
645645
/// # Security
646646
///
647-
/// The output of this function should not be used in anything that might have
648-
/// security implications. For example:
649-
///
650-
/// ```
651-
/// fn main() {
652-
/// println!("{:?}", std::env::current_exe());
653-
/// }
654-
/// ```
655-
///
656-
/// On Linux systems, if this is compiled as `foo`:
657-
///
658-
/// ```bash
659-
/// $ rustc foo.rs
660-
/// $ ./foo
661-
/// Ok("/home/alex/foo")
662-
/// ```
663-
///
664-
/// And you make a hard link of the program:
665-
///
666-
/// ```bash
667-
/// $ ln foo bar
668-
/// ```
669-
///
670-
/// When you run it, you won’t get the path of the original executable, you’ll
671-
/// get the path of the hard link:
672-
///
673-
/// ```bash
674-
/// $ ./bar
675-
/// Ok("/home/alex/bar")
676-
/// ```
647+
/// The output of this function should not be trusted for anything
648+
/// that might have security implications. Basically, if users can run
649+
/// the executable, they can change the output arbitrarily.
650+
///
651+
/// As an example, you can easily introduce a race condition. It goes
652+
/// like this:
653+
///
654+
/// 1. You get the path to the current executable using `current_exe()`, and
655+
/// store it in a variable.
656+
/// 2. Time passes. A malicious actor removes the current executable, and
657+
/// replaces it with a malicious one.
658+
/// 3. You then use the stored path to re-execute the current
659+
/// executable.
660+
///
661+
/// You expected to safely execute the current executable, but you're
662+
/// instead executing something completely different. The code you
663+
/// just executed run with your privileges.
677664
///
678665
/// This sort of behavior has been known to [lead to privilege escalation] when
679666
/// used incorrectly.

0 commit comments

Comments
 (0)