Skip to content

Commit a5dbdee

Browse files
committed
Error when there is an unsupported flag
1 parent e10d9d3 commit a5dbdee

File tree

1 file changed

+25
-4
lines changed

1 file changed

+25
-4
lines changed

src/shims/io.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
4444

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

47-
// The first two bits of the flag correspond to the access mode of the file in linux.
47+
// The first two bits of the flag correspond to the access mode of the file in linux. This
48+
// is done this way because `O_RDONLY` is zero in several platforms.
4849
let access_mode = flag & 0b11;
4950

5051
if access_mode == this.eval_libc_i32("O_RDONLY")? {
@@ -56,15 +57,35 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
5657
} else {
5758
throw_unsup_format!("Unsupported access mode {:#x}", access_mode);
5859
}
60+
// We need to check that there aren't unsupported options in `flag`. For this we try to
61+
// reproduce the content of `flag` in the `mirror` variable using only the supported
62+
// options.
63+
let mut mirror = access_mode;
5964

60-
if flag & this.eval_libc_i32("O_APPEND")? != 0 {
65+
let o_append = this.eval_libc_i32("O_APPEND")?;
66+
if flag & o_append != 0 {
6167
options.append(true);
68+
mirror |= o_append;
6269
}
63-
if flag & this.eval_libc_i32("O_TRUNC")? != 0 {
70+
let o_trunc = this.eval_libc_i32("O_TRUNC")?;
71+
if flag & o_trunc != 0 {
6472
options.truncate(true);
73+
mirror |= o_trunc;
6574
}
66-
if flag & this.eval_libc_i32("O_CREAT")? != 0 {
75+
let o_creat = this.eval_libc_i32("O_CREAT")?;
76+
if flag & o_creat != 0 {
6777
options.create(true);
78+
mirror |= o_creat;
79+
}
80+
let o_cloexec = this.eval_libc_i32("O_CLOEXEC")?;
81+
if flag & o_cloexec != 0 {
82+
// This flag is a noop for now because `std` already sets it.
83+
mirror |= o_cloexec;
84+
}
85+
// If `flag` is not equal to `mirror`, there is an unsupported option enabled in `flag`,
86+
// then we throw an error.
87+
if flag != mirror {
88+
throw_unsup_format!("unsupported flags {:#x}", flag);
6889
}
6990

7091
let path_bytes = this

0 commit comments

Comments
 (0)