about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorAleksa Sarai <cyphar@cyphar.com>2019-07-06 00:51:19 +1000
committerAleksa Sarai <cyphar@cyphar.com>2019-07-10 23:59:46 +1000
commit6031a07a464eae202cc43fbb15fada094171488d (patch)
treed7cab21a0799626ec0ddac28a5a1e4dd2c51e568 /src/libstd
parent481068a707679257e2a738b40987246e0420e787 (diff)
downloadrust-6031a07a464eae202cc43fbb15fada094171488d.tar.gz
rust-6031a07a464eae202cc43fbb15fada094171488d.zip
filedesc: don't use ioctl(FIOCLEX) on Linux
All ioctl(2)s will fail on O_PATH file descriptors on Linux (because
they use &empty_fops as a security measure against O_PATH descriptors
affecting the backing file).

As a result, File::try_clone() and various other methods would always
fail with -EBADF on O_PATH file descriptors. The solution is to simply
use F_SETFD (as is used on other unices) which works on O_PATH
descriptors because it operates through the fnctl(2) layer and not
through ioctl(2)s.

Since this code is usually only used in strange error paths (a broken or
ancient kernel), the extra overhead of one syscall shouldn't cause any
dramas. Most other systems programming languages also use the fnctl(2)
so this brings us in line with them.

Fixes: rust-lang/rust#62314
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/sys/unix/fd.rs2
1 files changed, 2 insertions, 0 deletions
diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs
index 6d23963e141..0cecdd7ffa0 100644
--- a/src/libstd/sys/unix/fd.rs
+++ b/src/libstd/sys/unix/fd.rs
@@ -175,6 +175,7 @@ impl FileDesc {
                   target_os = "emscripten",
                   target_os = "fuchsia",
                   target_os = "l4re",
+                  target_os = "linux",
                   target_os = "haiku")))]
     pub fn set_cloexec(&self) -> io::Result<()> {
         unsafe {
@@ -187,6 +188,7 @@ impl FileDesc {
               target_os = "emscripten",
               target_os = "fuchsia",
               target_os = "l4re",
+              target_os = "linux",
               target_os = "haiku"))]
     pub fn set_cloexec(&self) -> io::Result<()> {
         unsafe {