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

current_exe() returns invalid path on linux when exe has been deleted #69343

Open
tsurai opened this issue Feb 21, 2020 · 12 comments
Open

current_exe() returns invalid path on linux when exe has been deleted #69343

tsurai opened this issue Feb 21, 2020 · 12 comments
Labels
C-bug Category: This is a bug. O-linux Operating system: Linux T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@tsurai
Copy link
Contributor

tsurai commented Feb 21, 2020

Calling current_exe() on linux after the original executable has been deleted or replaced results in an invalid path being returned.

fn main() {
    // current_exe = /path/to/executable
    remove_file(current_exe().unwrap()).ok();
    println!("{:?}", current_exe());
}

Output

Ok("/path/to/executable (deleted)")

Desired behavior

While it is the correct behavior of the underlying /proc/self/exe to append the string (deleted) to the original pathname the result is not a valid path and might even end up pointing to a completely different file.

I would either expect the docs to explicitly mention this behavior or classify it as an error and return io::ErrorKind::NotFound accordingly.

Meta

rustc --version --verbose:

rustc 1.41.0 (5e1a79984 2020-01-27)
binary: rustc
commit-hash: 5e1a799842ba6ed4a57e91f7ab9435947482f7d8
commit-date: 2020-01-27
host: x86_64-unknown-linux-gnu
release: 1.41.0
LLVM version: 9.0

I would gladly claim this issue if you agree to it.

@tsurai tsurai added the C-bug Category: This is a bug. label Feb 21, 2020
@jonas-schievink jonas-schievink added O-linux Operating system: Linux T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Feb 21, 2020
@the8472
Copy link
Member

the8472 commented Feb 21, 2020

Since (deleted) is a valid unix path it would take extra syscalls to check if it actually exists. Additionally there are other cases where /proc/self/exe may point to something that's not accessible, e.g. when mount namespaces or chroot are in play or when a process was launched via memfd_create + fexecve.

So it probably needs a doc update. In the case of mount namespaces this might also be subject to confusion attacks, so this value generally shouldn't be given too much trust.

@clarfonthey
Copy link
Contributor

Rather than simply checking for " (deleted)", it makes more sense to open and stat /proc/self/exe and the path returned. If the inos are different, then the currently running binary isn't the same as the one at the path (it's been replaced or deleted) and an error should be returned.

IMHO. This doesn't explicitly go against the docs on current_exe and I think it'd be good to support that behaviour.

@tesuji
Copy link
Contributor

tesuji commented Feb 24, 2020

Isn't it Linux only?

@tsurai
Copy link
Contributor Author

tsurai commented Feb 24, 2020

While current_exe() might return all kinds of different paths caused by symlinks or mounts it should return something that points to the executable even if you might not have the permissions to access it.

But /path/to/exe (deleted) has at no point in time been the correct path for the executable and should thus be considered an error. In the end it comes down to how the libraries subteam wants to handle this.

@the8472
Copy link
Member

the8472 commented Feb 24, 2020

Rather than simply checking for " (deleted)", it makes more sense to open and stat /proc/self/exe and the path returned. If the inos are different, then the currently running binary isn't the same as the one at the path

Does /proc/<pid>/exe have similar magical properties to /proc/<pid>/fd/*?

@clarfonthey
Copy link
Contributor

Isn't it Linux only?

Does /proc/<pid>/exe have similar magical properties to /proc/<pid>/fd/*?

Yes and yes.

@the8472
Copy link
Member

the8472 commented Feb 27, 2020

Then another option is to simply return the symlink itself instead of the target. At least as a fallback.

After all it may be the only existing reference to an inode, e.g. in the mem_fd case

@bjorn3
Copy link
Member

bjorn3 commented Feb 27, 2020

That won't work if you pass the result of current_exe to another process and then exit.

@the8472
Copy link
Member

the8472 commented Feb 27, 2020

If that symlink was the last reference to the inode then it will never work. So if it's just a fallback you don't lose anything.

@Kixunil
Copy link
Contributor

Kixunil commented Apr 23, 2020

Returning the symlink itself would be a bad idea, even if /proc/<ID>/fd was returned:

  • Debugging purpose would break
  • Calculating parent directory would break
  • Even if the program doesn't exist, giving /proc/self/exe to another program would cause that other program to point to itself.

@the8472
Copy link
Member

the8472 commented Apr 23, 2020

Even if the program doesn't exist, giving /proc/self/exe to another program would cause that other program to point to itself.

You would pass /proc/<pid>/exe which is valid for the lifetime of the program.

But yes, all of these are workarounds with their own limitations. The proper solution is, at least on linux, to pass around file descriptors which are valid for their whole existence.

@clarfonthey
Copy link
Contributor

As i mentioned in the other thread, it may be worth just deprecating this API in favour of another crate which offers multiple options with different guarantees.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. O-linux Operating system: Linux T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants