Skip to content

Error when there is an unsupported flag for opening a file #987

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 16, 2019
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 29 additions & 26 deletions src/shims/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx

let mut options = OpenOptions::new();

// The first two bits of the flag correspond to the access mode of the file in linux.
// 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 access_mode = flag & 0b11;

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

if flag & this.eval_libc_i32("O_APPEND")? != 0 {
let o_append = this.eval_libc_i32("O_APPEND")?;
if flag & o_append != 0 {
options.append(true);
mirror |= o_append;
}
if flag & this.eval_libc_i32("O_TRUNC")? != 0 {
let o_trunc = this.eval_libc_i32("O_TRUNC")?;
if flag & o_trunc != 0 {
options.truncate(true);
mirror |= o_trunc;
}
if flag & this.eval_libc_i32("O_CREAT")? != 0 {
let o_creat = this.eval_libc_i32("O_CREAT")?;
if flag & o_creat != 0 {
options.create(true);
mirror |= o_creat;
}
let o_cloexec = this.eval_libc_i32("O_CLOEXEC")?;
if flag & o_cloexec != 0 {
// This flag is a noop for now because `std` already sets it.
mirror |= o_cloexec;
}
// If `flag` is not equal to `mirror`, there is an unsupported option enabled in `flag`,
// then we throw an error.
if flag != mirror {
throw_unsup_format!("unsupported flags {:#x}", flag);
}

let path_bytes = this
Expand All @@ -87,7 +108,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
&mut self,
fd_op: OpTy<'tcx, Tag>,
cmd_op: OpTy<'tcx, Tag>,
arg_op: Option<OpTy<'tcx, Tag>>,
_arg_op: Option<OpTy<'tcx, Tag>>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();

Expand All @@ -97,29 +118,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx

let fd = this.read_scalar(fd_op)?.to_i32()?;
let cmd = this.read_scalar(cmd_op)?.to_i32()?;

if cmd == this.eval_libc_i32("F_SETFD")? {
// This does not affect the file itself. Certain flags might require changing the file
// or the way it is accessed somehow.
let flag = this.read_scalar(arg_op.unwrap())?.to_i32()?;
// The only usage of this in stdlib at the moment is to enable the `FD_CLOEXEC` flag.
let fd_cloexec = this.eval_libc_i32("FD_CLOEXEC")?;
if let Some(FileHandle { flag: old_flag, .. }) =
this.machine.file_handler.handles.get_mut(&fd)
{
// Check that the only difference between the old flag and the current flag is
// exactly the `FD_CLOEXEC` value.
if flag ^ *old_flag == fd_cloexec {
*old_flag = flag;
} else {
throw_unsup_format!("Unsupported arg {:#x} for `F_SETFD`", flag);
}
}
Ok(0)
} else if cmd == this.eval_libc_i32("F_GETFD")? {
// We only support getting the flags for a descriptor
if cmd == this.eval_libc_i32("F_GETFD")? {
this.get_handle_and(fd, |handle| Ok(handle.flag))
} else {
throw_unsup_format!("Unsupported command {:#x}", cmd);
throw_unsup_format!("The {:#x} command is not supported for `fcntl`)", cmd);
}
}

Expand Down