Skip to content

Commit

Permalink
Merge #1433
Browse files Browse the repository at this point in the history
1433: Use fstatat to check long path sizes in fcntl::readlinkat r=asomers a=zxzax

Without this, the `lstat` call ignores the `dirfd` and checks the wrong file. I wanted to write a unit test for this but I'm not sure how to do it reliably, AFAIK the maximum path size can vary between filesystems.

Co-authored-by: Jason Francis <[email protected]>
  • Loading branch information
bors[bot] and Jason Francis authored May 23, 2021
2 parents 86dde6c + 41fa8e2 commit dc07f61
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion src/fcntl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,18 @@ fn inner_readlink<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P) -> Result
}
// Uh oh, the result is too long...
// Let's try to ask lstat how many bytes to allocate.
let reported_size = super::sys::stat::lstat(path)
let reported_size = match dirfd {
#[cfg(target_os = "redox")]
Some(_) => unreachable!(),
#[cfg(any(target_os = "android", target_os = "linux"))]
Some(dirfd) => {
let flags = if path.is_empty() { AtFlags::AT_EMPTY_PATH } else { AtFlags::empty() };
super::sys::stat::fstatat(dirfd, path, flags | AtFlags::AT_SYMLINK_NOFOLLOW)
},
#[cfg(not(any(target_os = "android", target_os = "linux", target_os = "redox")))]
Some(dirfd) => super::sys::stat::fstatat(dirfd, path, AtFlags::AT_SYMLINK_NOFOLLOW),
None => super::sys::stat::lstat(path)
}
.and_then(|x| Ok(x.st_size))
.unwrap_or(0);
let mut try_size = if reported_size > 0 {
Expand Down

0 comments on commit dc07f61

Please sign in to comment.