Skip to content

std::fs::symlink_metadata + set_permissions makes unintuitive behavior #124201

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

Closed
youknowone opened this issue Apr 20, 2024 · 4 comments · Fixed by #139546
Closed

std::fs::symlink_metadata + set_permissions makes unintuitive behavior #124201

youknowone opened this issue Apr 20, 2024 · 4 comments · Fixed by #139546
Labels
A-docs Area: Documentation for any part of the project, including the compiler, standard library, and tools A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Comments

@youknowone
Copy link
Contributor

youknowone commented Apr 20, 2024

Location

std::fs::symlink_metadata or std::fs::set_permissions

Summary

fn main() -> std::io::Result<()> {
  use std::os::unix::fs::PermissionsExt;

  let path = std::path::PathBuf::from("bar");   // `bar` is a symlink
  let meta = std::fs::symlink_metadata(&path)?;
  let mut permissions = meta.permissions();
  println!("current mode: {:o}", permissions.mode());
  permissions.set_mode(0o707);
  println!("new mode: {:o}", permissions.mode());

  std::fs::set_permissions(&path, permissions)?;  // applied permission to original file

  let meta = std::fs::symlink_metadata(&path)?;
  let mut permissions = meta.permissions();
  println!("reloaded mode: {:o}", permissions.mode());
  Ok(())
}
current mode: 120755
new mode: 707
reloaded mode: 120755

Since I could obtain metadata for either original file or symlink, I expected there must be a way to apply permissions to symlink. But symlink_metadata revealed not to have a pair of set_permissions.

By the design if it is intended or lack of API, it could be documented somewhere like symlink_metadata or set_permissions.

On the other hand, metadata is obtainable from either file or symlink. Then I expected set_permission to be placed on metadata object if metadata includes symlink information.
e.g. metadata.set_permissions(path, permissions)

@youknowone youknowone added the A-docs Area: Documentation for any part of the project, including the compiler, standard library, and tools label Apr 20, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Apr 20, 2024
@the8472
Copy link
Member

the8472 commented Apr 20, 2024

symlink permissions have no effect or can't be set on most unixes, therefore setting them does not make sense as a portable API.

https://superuser.com/a/1188707

@youknowone
Copy link
Contributor Author

I agree that point. macOS and a few more BSDs are affect by this. Adding a short warning will make sense.

@saethlin saethlin added A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels May 7, 2024
@lolbinarycat
Copy link
Contributor

both versions of set_permissions should have a warning about their interactions with symlinks, as this mistake lead to CVE-2025-27591.

@lolbinarycat
Copy link
Contributor

perhaps it would even be worth making a set_permissions_nofollow that fails if it is used on a symlink, to avoid repeating this vulnerability.

ChrisDenton added a commit to ChrisDenton/rust that referenced this issue Apr 28, 2025
…5942, r=thomcc

std(docs): clarify how std::fs::set_permisions works with symlinks

fixes rust-lang#75942
fixes rust-lang#124201
ChrisDenton added a commit to ChrisDenton/rust that referenced this issue Apr 28, 2025
…5942, r=thomcc

std(docs): clarify how std::fs::set_permisions works with symlinks

fixes rust-lang#75942
fixes rust-lang#124201
ChrisDenton added a commit to ChrisDenton/rust that referenced this issue Apr 28, 2025
…5942, r=thomcc

std(docs): clarify how std::fs::set_permisions works with symlinks

fixes rust-lang#75942
fixes rust-lang#124201
@bors bors closed this as completed in 8808d5a Apr 28, 2025
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Apr 28, 2025
Rollup merge of rust-lang#139546 - lolbinarycat:std-set_permissions-75942, r=thomcc

std(docs): clarify how std::fs::set_permisions works with symlinks

fixes rust-lang#75942
fixes rust-lang#124201
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-docs Area: Documentation for any part of the project, including the compiler, standard library, and tools A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants