summaryrefslogtreecommitdiff
path: root/src/fcntl.rs
diff options
context:
space:
mode:
authorJason Francis <zxzax@protonmail.com>2021-05-11 12:16:06 -0400
committerJason Francis <zxzax@protonmail.com>2021-05-23 10:35:24 -0400
commit41fa8e2a26fb053820730f524e78810a6f1c6173 (patch)
treeae009d0287404abaf3e1bca9a290781ffbeaf4bb /src/fcntl.rs
parent86dde6c33d4a923013f61406587c8ddf9c50b248 (diff)
downloadnix-41fa8e2a26fb053820730f524e78810a6f1c6173.zip
Use fstatat to check long path sizes in fcntl::readlinkat
Diffstat (limited to 'src/fcntl.rs')
-rw-r--r--src/fcntl.rs13
1 files changed, 12 insertions, 1 deletions
diff --git a/src/fcntl.rs b/src/fcntl.rs
index 9da7d33f..2532724b 100644
--- a/src/fcntl.rs
+++ b/src/fcntl.rs
@@ -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 {