Skip to content

Commit 2487223

Browse files
committed
Check that access mode flags only use the first two bits
1 parent f76f8ce commit 2487223

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

src/shims/fs.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,23 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
4343

4444
let mut options = OpenOptions::new();
4545

46-
// The first two bits of the flag correspond to the access mode of the file in linux. This
47-
// is done this way because `O_RDONLY` is zero in several platforms.
46+
let o_rdonly = this.eval_libc_i32("O_RDONLY")?;
47+
let o_wronly = this.eval_libc_i32("O_WRONLY")?;
48+
let o_rdwr = this.eval_libc_i32("O_RDWR")?;
49+
// The first two bits of the flag correspond to the access mode in linux, macOS and
50+
// windows. We need to check that in fact the access mode flags for the current platform
51+
// only use these two bits, otherwise we are in an unsupported platform and should error.
52+
if (o_rdonly | o_wronly | o_rdwr) & !0b11 != 0 {
53+
throw_unsup_format!("Access mode flags on this platform are unsupported");
54+
}
55+
// Now we check the access mode
4856
let access_mode = flag & 0b11;
4957

50-
if access_mode == this.eval_libc_i32("O_RDONLY")? {
58+
if access_mode == o_rdonly {
5159
options.read(true);
52-
} else if access_mode == this.eval_libc_i32("O_WRONLY")? {
60+
} else if access_mode == o_wronly {
5361
options.write(true);
54-
} else if access_mode == this.eval_libc_i32("O_RDWR")? {
62+
} else if access_mode == o_rdwr {
5563
options.read(true).write(true);
5664
} else {
5765
throw_unsup_format!("Unsupported access mode {:#x}", access_mode);
@@ -124,8 +132,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
124132
// `FD_CLOEXEC` value without checking if the flag is set for the file because `std`
125133
// always sets this flag when opening a file. However we still need to check that the
126134
// file itself is open.
127-
this.get_handle_and(fd, |_| Ok(0))?;
128-
this.eval_libc_i32("FD_CLOEXEC")
135+
let fd_cloexec = this.eval_libc_i32("FD_CLOEXEC")?;
136+
this.get_handle_and(fd, |_| Ok(fd_cloexec))
129137
} else {
130138
throw_unsup_format!("The {:#x} command is not supported for `fcntl`)", cmd);
131139
}

0 commit comments

Comments
 (0)