Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some warnings to std::env::current_exe #33526

Merged
merged 2 commits into from
Jul 20, 2016
Merged

Conversation

steveklabnik
Copy link
Member

/cc #21889 @rust-lang/libs @semarie

I started writing this up. I'm not sure if we want to go into other things and in what depth; we don't currently have a lot of security-specific documentation to model after.

Thoughts?

@rust-highfive
Copy link
Collaborator

r? @aturon

(rust_highfive has picked a reviewer for you, use r? to override)

@brson
Copy link
Contributor

brson commented May 9, 2016

lgtm

/// # Security
///
/// This function should be used with care, as its incorrect usage can cause
/// security problems. Specifically, as with many operations invovling files and
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"invovling"

@alexcrichton
Copy link
Member

Thanks @steveklabnik! Perhaps we could emphasize that calling this function itself only has security implications if you assume some property about the return value which may have security implications? I don't find the example of overwriting something too compelling because if you can overwrite the executable then you can, well, overwrite the executable (as in, current_exe is the least of your privileges).

The real problem here is you can escalate privileges, which I found this example to be the most compelling. You can trivially cause std::env::current_exe() to return something arbitrary, for example:

$ echo 'fn main() { println!("{:?}", std::env::current_exe()); }' > foo.rs
$ rustc foo.rs
$ ./foo
Ok("/home/alex/foo")
$ ln foo bar
$ ./bar
Ok("/home/alex/bar")

For example I would consider the compiler's usage of this function "not insecure" because although you could cause rustc to link against a random libstd, it's already generating arbitrary code... The problem in that linked post was that the path would be used for executing an executable as root, which is clearly going to end badly if you can run arbitrary executables.

@semarie
Copy link
Contributor

semarie commented May 10, 2016

@alexcrichton if you call the function, it is for the returned pathname (you don't call it just for a side effect): so you always assume one property: you will get the pathname of the running executable.

One problem is the moving definition of the returned pathname against the platform.
It could be:

  • the pathname used at execve(2) time (the pathname doesn't change if the file is moved)
  • a best effort for having the pathname of the running executable (one OS which store it in some cache system, and under memory pressure could be flushed - or some other failure conditions)
  • an error because the file was deleted or moved
  • an error because the platform don't support retrieving this information
  • or always the good pathname (even if moved) or an error if removed (the better implementation)

So basically, if you got a pathname, you couldn't assume the pathname will be the right one.

@steveklabnik I think your description is good enough. Maybe just add a note for saying that the accuracy of the returned pathname is platform dependant (and so should be assumed to be wrong) ?

@steveklabnik steveklabnik deleted the gh21889 branch June 19, 2016 20:29
@semarie
Copy link
Contributor

semarie commented Jun 20, 2016

so, no documentation warning at all ?

@steveklabnik
Copy link
Member Author

Whoops. I was looking at my "open PRs" and saw only the one I just sent. I then cleaned up a lot of my old branches. I guess this PR was still outstanding? Will re-send later today.

@steveklabnik steveklabnik restored the gh21889 branch June 20, 2016 11:36
@steveklabnik steveklabnik reopened this Jun 20, 2016
@alexcrichton
Copy link
Member

@steveklabnik thoughts on updating with some of the discussion above?

@steveklabnik
Copy link
Member Author

I will get on it today.

@steveklabnik
Copy link
Member Author

Updated, to use the more real example, and link to the vulnerability. I do think that it's stronger as an example. Still not totally happy with the wording here, but it might be Good Enough.

@alexcrichton
Copy link
Member

@bors: r+ c4730da

Looks good to me!

@bors
Copy link
Contributor

bors commented Jul 19, 2016

⌛ Testing commit c4730da with merge 5dd7e83...

@bors
Copy link
Contributor

bors commented Jul 19, 2016

💔 Test failed - auto-win-msvc-64-opt

@alexcrichton
Copy link
Member

@bors: retry

On Tue, Jul 19, 2016 at 12:36 PM, bors [email protected] wrote:

💔 Test failed - auto-win-msvc-64-opt
https://buildbot.rust-lang.org/builders/auto-win-msvc-64-opt/builds/4933


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#33526 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAD95IpBc9hViyMAIEvOr83UF2giUiewks5qXSc6gaJpZM4IaoUC
.

@bors
Copy link
Contributor

bors commented Jul 20, 2016

⌛ Testing commit c4730da with merge 008e473...

@bors
Copy link
Contributor

bors commented Jul 20, 2016

💔 Test failed - auto-linux-64-debug-opt

@alexcrichton
Copy link
Member

@bors: retry

On Tue, Jul 19, 2016 at 9:02 PM, bors [email protected] wrote:

💔 Test failed - auto-linux-64-debug-opt
https://buildbot.rust-lang.org/builders/auto-linux-64-debug-opt/builds/3124


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#33526 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAD95MUEi4sy17nbUihgbjaVEYJ5h2vfks5qXZ3NgaJpZM4IaoUC
.

@bors
Copy link
Contributor

bors commented Jul 20, 2016

⌛ Testing commit c4730da with merge 46d67fc...

@bors
Copy link
Contributor

bors commented Jul 20, 2016

⛄ The build was interrupted to prioritize another pull request.

@bors
Copy link
Contributor

bors commented Jul 20, 2016

⌛ Testing commit c4730da with merge cf04494...

@bors
Copy link
Contributor

bors commented Jul 20, 2016

💔 Test failed - auto-win-msvc-64-opt-rustbuild

@alexcrichton
Copy link
Member

@bors: retry

@bors
Copy link
Contributor

bors commented Jul 20, 2016

⌛ Testing commit c4730da with merge b334e04...

@bors
Copy link
Contributor

bors commented Jul 20, 2016

⛄ The build was interrupted to prioritize another pull request.

@bors
Copy link
Contributor

bors commented Jul 20, 2016

⌛ Testing commit c4730da with merge 49fe9d0...

@bors
Copy link
Contributor

bors commented Jul 20, 2016

💔 Test failed - auto-win-msvc-64-cargotest

@alexcrichton
Copy link
Member

@bors: retry

On Tue, Jul 19, 2016 at 11:04 PM, bors [email protected] wrote:

💔 Test failed - auto-win-msvc-64-cargotest
https://buildbot.rust-lang.org/builders/auto-win-msvc-64-cargotest/builds/1183


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#33526 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAD95Cqnc9KMidHoAuR_dKE_R-jCyhfLks5qXbpfgaJpZM4IaoUC
.

@bors
Copy link
Contributor

bors commented Jul 20, 2016

⌛ Testing commit c4730da with merge a63e3fa...

bors added a commit that referenced this pull request Jul 20, 2016
Add some warnings to std::env::current_exe

/cc #21889 @rust-lang/libs @semarie

I started writing this up. I'm not sure if we want to go into other things and in what depth; we don't currently have a lot of security-specific documentation to model after.

Thoughts?
@bors bors merged commit c4730da into rust-lang:master Jul 20, 2016
@semarie
Copy link
Contributor

semarie commented Jul 20, 2016

thanks

mgeisler added a commit to mgeisler/rust that referenced this pull request May 3, 2022
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 rust-lang#33526. That PR actually has two commits, and the
first (8478d48) 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 rust-lang#33526.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request May 7, 2022
…ark-Simulacrum

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 rust-lang#33526. That PR actually has two commits, and the first (rust-lang@8478d48) 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 rust-lang#33526.
workingjubilee pushed a commit to tcdi/postgrestd that referenced this pull request Sep 15, 2022
…acrum

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 rust-lang/rust#33526. That PR actually has two commits, and the first (rust-lang/rust@8478d48) 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 rust-lang/rust#33526.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants