From: Christian Poveda Date: Mon, 14 Oct 2019 21:42:29 +0000 (-0500) Subject: Check that access mode flags only use the first two bits X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=24872230dc25f40b5683549bdb1e288964744e77;p=rust.git Check that access mode flags only use the first two bits --- diff --git a/src/shims/fs.rs b/src/shims/fs.rs index 4d93ca4fd31..c3dc5e60f0b 100644 --- a/src/shims/fs.rs +++ b/src/shims/fs.rs @@ -43,15 +43,23 @@ fn open( let mut options = OpenOptions::new(); - // The first two bits of the flag correspond to the access mode of the file in linux. This - // is done this way because `O_RDONLY` is zero in several platforms. + let o_rdonly = this.eval_libc_i32("O_RDONLY")?; + let o_wronly = this.eval_libc_i32("O_WRONLY")?; + let o_rdwr = this.eval_libc_i32("O_RDWR")?; + // The first two bits of the flag correspond to the access mode in linux, macOS and + // windows. We need to check that in fact the access mode flags for the current platform + // only use these two bits, otherwise we are in an unsupported platform and should error. + if (o_rdonly | o_wronly | o_rdwr) & !0b11 != 0 { + throw_unsup_format!("Access mode flags on this platform are unsupported"); + } + // Now we check the access mode let access_mode = flag & 0b11; - if access_mode == this.eval_libc_i32("O_RDONLY")? { + if access_mode == o_rdonly { options.read(true); - } else if access_mode == this.eval_libc_i32("O_WRONLY")? { + } else if access_mode == o_wronly { options.write(true); - } else if access_mode == this.eval_libc_i32("O_RDWR")? { + } else if access_mode == o_rdwr { options.read(true).write(true); } else { throw_unsup_format!("Unsupported access mode {:#x}", access_mode); @@ -124,8 +132,8 @@ fn fcntl( // `FD_CLOEXEC` value without checking if the flag is set for the file because `std` // always sets this flag when opening a file. However we still need to check that the // file itself is open. - this.get_handle_and(fd, |_| Ok(0))?; - this.eval_libc_i32("FD_CLOEXEC") + let fd_cloexec = this.eval_libc_i32("FD_CLOEXEC")?; + this.get_handle_and(fd, |_| Ok(fd_cloexec)) } else { throw_unsup_format!("The {:#x} command is not supported for `fcntl`)", cmd); }