Skip to content

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

New issue

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

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

Already on GitHub? # to your account

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

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

youknowone opened this issue Apr 20, 2024 · 5 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
@youknowone
Copy link
Contributor Author

Thanks @lolbinarycat

github-actions bot pushed a commit to model-checking/verify-rust-std that referenced this issue May 9, 2025
github-actions bot pushed a commit to model-checking/verify-rust-std that referenced this issue May 9, 2025
…5942, r=thomcc

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

fixes rust-lang#75942
fixes rust-lang#124201
# for free to join this conversation on GitHub. Already have an account? # 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