Skip to content

Commit

Permalink
Clear more eval_libc errors from unix shims
Browse files Browse the repository at this point in the history
  • Loading branch information
noahmbright committed Oct 25, 2024
1 parent 340d2f7 commit c1004ff
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 53 deletions.
9 changes: 3 additions & 6 deletions src/tools/miri/src/shims/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,8 +447,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
} else {
// If this does not fit in an isize, return null and, on Unix, set errno.
if this.target_os_is_unix() {
let einval = this.eval_libc("ENOMEM");
this.set_last_error(einval)?;
this.set_last_error(LibcError("ENOMEM"))?;
}
this.write_null(dest)?;
}
Expand All @@ -464,8 +463,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
} else {
// On size overflow, return null and, on Unix, set errno.
if this.target_os_is_unix() {
let einval = this.eval_libc("ENOMEM");
this.set_last_error(einval)?;
this.set_last_error(LibcError("ENOMEM"))?;
}
this.write_null(dest)?;
}
Expand All @@ -486,8 +484,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
} else {
// If this does not fit in an isize, return null and, on Unix, set errno.
if this.target_os_is_unix() {
let einval = this.eval_libc("ENOMEM");
this.set_last_error(einval)?;
this.set_last_error(LibcError("ENOMEM"))?;
}
this.write_null(dest)?;
}
Expand Down
12 changes: 3 additions & 9 deletions src/tools/miri/src/shims/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
} else if relative_clocks.contains(&clk_id) {
this.machine.clock.now().duration_since(this.machine.clock.epoch())
} else {
let einval = this.eval_libc("EINVAL");
this.set_last_error(einval)?;
return interp_ok(Scalar::from_i32(-1));
return this.set_last_error_and_return_i32(LibcError("EINVAL"));
};

let tv_sec = duration.as_secs();
Expand All @@ -109,9 +107,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Using tz is obsolete and should always be null
let tz = this.read_pointer(tz_op)?;
if !this.ptr_is_null(tz)? {
let einval = this.eval_libc("EINVAL");
this.set_last_error(einval)?;
return interp_ok(Scalar::from_i32(-1));
return this.set_last_error_and_return_i32(LibcError("EINVAL"));
}

let duration = system_time_to_duration(&SystemTime::now())?;
Expand Down Expand Up @@ -323,9 +319,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
let duration = match this.read_timespec(&req)? {
Some(duration) => duration,
None => {
let einval = this.eval_libc("EINVAL");
this.set_last_error(einval)?;
return interp_ok(Scalar::from_i32(-1));
return this.set_last_error_and_return_i32(LibcError("EINVAL"));
}
};

Expand Down
25 changes: 7 additions & 18 deletions src/tools/miri/src/shims/unix/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,8 +362,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// FreeBSD: https://man.freebsd.org/cgi/man.cgi?query=reallocarray
match this.compute_size_in_bytes(Size::from_bytes(size), nmemb) {
None => {
let enmem = this.eval_libc("ENOMEM");
this.set_last_error(enmem)?;
this.set_last_error(LibcError("ENOMEM"))?;
this.write_null(dest)?;
}
Some(len) => {
Expand Down Expand Up @@ -653,13 +652,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
let chunk_size = CpuAffinityMask::chunk_size(this);

if this.ptr_is_null(mask)? {
let efault = this.eval_libc("EFAULT");
this.set_last_error(efault)?;
this.write_int(-1, dest)?;
this.set_last_error_and_return(LibcError("EFAULT"), dest)?;
} else if cpusetsize == 0 || cpusetsize.checked_rem(chunk_size).unwrap() != 0 {
// we only copy whole chunks of size_of::<c_ulong>()
this.set_last_error(LibcError("EINVAL"))?;
this.write_int(-1, dest)?;
this.set_last_error_and_return(LibcError("EINVAL"), dest)?;
} else if let Some(cpuset) = this.machine.thread_cpu_affinity.get(&thread_id) {
let cpuset = cpuset.clone();
// we only copy whole chunks of size_of::<c_ulong>()
Expand All @@ -668,9 +664,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.write_null(dest)?;
} else {
// The thread whose ID is pid could not be found
let esrch = this.eval_libc("ESRCH");
this.set_last_error(esrch)?;
this.write_int(-1, dest)?;
this.set_last_error_and_return(LibcError("ESRCH"), dest)?;
}
}
"sched_setaffinity" => {
Expand All @@ -695,9 +689,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
};

if this.ptr_is_null(mask)? {
let efault = this.eval_libc("EFAULT");
this.set_last_error(efault)?;
this.write_int(-1, dest)?;
this.set_last_error_and_return(LibcError("EFAULT"), dest)?;
} else {
// NOTE: cpusetsize might be smaller than `CpuAffinityMask::CPU_MASK_BYTES`.
// Any unspecified bytes are treated as zero here (none of the CPUs are configured).
Expand All @@ -713,8 +705,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
}
None => {
// The intersection between the mask and the available CPUs was empty.
this.set_last_error(LibcError("EINVAL"))?;
this.write_int(-1, dest)?;
this.set_last_error_and_return(LibcError("EINVAL"), dest)?;
}
}
}
Expand Down Expand Up @@ -770,9 +761,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// macOS: https://keith.github.io/xcode-man-pages/getentropy.2.html
// Solaris/Illumos: https://illumos.org/man/3C/getentropy
if bufsize > 256 {
let err = this.eval_libc("EIO");
this.set_last_error(err)?;
this.write_int(-1, dest)?;
this.set_last_error_and_return(LibcError("EIO"), dest)?;
} else {
this.gen_random(buf, bufsize)?;
this.write_null(dest)?;
Expand Down
17 changes: 7 additions & 10 deletions src/tools/miri/src/shims/unix/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -787,13 +787,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
let ecode = if path.is_absolute() || dirfd == this.eval_libc_i32("AT_FDCWD") {
// since `path` is provided, either absolute or
// relative to CWD, `EACCES` is the most relevant.
this.eval_libc("EACCES")
LibcError("EACCES")
} else {
// `dirfd` is set to target file, and `path` is empty
// (or we would have hit the `throw_unsup_format`
// above). `EACCES` would violate the spec.
assert!(empty_path_flag);
this.eval_libc("EBADF")
LibcError("EBADF")
};
return this.set_last_error_and_return_i32(ecode);
}
Expand Down Expand Up @@ -1031,8 +1031,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Reject if isolation is enabled.
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
this.reject_in_isolation("`readdir`", reject_with)?;
let eacc = this.eval_libc("EBADF");
this.set_last_error(eacc)?;
this.set_last_error(LibcError("EBADF"))?;
return interp_ok(Scalar::null_ptr(this));
}

Expand Down Expand Up @@ -1449,11 +1448,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
if fd.is_tty(this.machine.communicate()) {
return interp_ok(Scalar::from_i32(1));
} else {
this.eval_libc("ENOTTY")
LibcError("ENOTTY")
}
} else {
// FD does not exist
this.eval_libc("EBADF")
LibcError("EBADF")
};
this.set_last_error(error)?;
interp_ok(Scalar::from_i32(0))
Expand All @@ -1473,8 +1472,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Reject if isolation is enabled.
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
this.reject_in_isolation("`realpath`", reject_with)?;
let eacc = this.eval_libc("EACCES");
this.set_last_error(eacc)?;
this.set_last_error(LibcError("EACCES"))?;
return interp_ok(Scalar::from_target_usize(0, this));
}

Expand Down Expand Up @@ -1504,8 +1502,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Note that we do not explicitly handle `FILENAME_MAX`
// (different from `PATH_MAX` above) as it is Linux-specific and
// seems like a bit of a mess anyway: <https://eklitzke.org/path-max-is-tricky>.
let enametoolong = this.eval_libc("ENAMETOOLONG");
this.set_last_error(enametoolong)?;
this.set_last_error(LibcError("ENAMETOOLONG"))?;
return interp_ok(Scalar::from_target_usize(0, this));
}
processed_ptr
Expand Down
4 changes: 2 additions & 2 deletions src/tools/miri/src/shims/unix/linux/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// old_address must be a multiple of the page size
#[allow(clippy::arithmetic_side_effects)] // PAGE_SIZE is nonzero
if old_address.addr().bytes() % this.machine.page_size != 0 || new_size == 0 {
this.set_last_error(this.eval_libc("EINVAL"))?;
this.set_last_error(LibcError("EINVAL"))?;
return interp_ok(this.eval_libc("MAP_FAILED"));
}

Expand All @@ -38,7 +38,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {

if flags & this.eval_libc_i32("MREMAP_MAYMOVE") == 0 {
// We only support MREMAP_MAYMOVE, so not passing the flag is just a failure
this.set_last_error(this.eval_libc("EINVAL"))?;
this.set_last_error(LibcError("EINVAL"))?;
return interp_ok(this.eval_libc("MAP_FAILED"));
}

Expand Down
4 changes: 1 addition & 3 deletions src/tools/miri/src/shims/unix/linux/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,7 @@ pub fn futex<'tcx>(
} else {
// The futex value doesn't match the expected value, so we return failure
// right away without sleeping: -1 and errno set to EAGAIN.
let eagain = this.eval_libc("EAGAIN");
this.set_last_error(eagain)?;
this.write_scalar(Scalar::from_target_isize(-1, this), dest)?;
this.set_last_error_and_return(LibcError("EAGAIN"), dest)?;
}
}
// FUTEX_WAKE: (int *addr, int op = FUTEX_WAKE, int val)
Expand Down
10 changes: 5 additions & 5 deletions src/tools/miri/src/shims/unix/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {

// First, we do some basic argument validation as required by mmap
if (flags & (map_private | map_shared)).count_ones() != 1 {
this.set_last_error(this.eval_libc("EINVAL"))?;
this.set_last_error(LibcError("EINVAL"))?;
return interp_ok(this.eval_libc("MAP_FAILED"));
}
if length == 0 {
this.set_last_error(this.eval_libc("EINVAL"))?;
this.set_last_error(LibcError("EINVAL"))?;
return interp_ok(this.eval_libc("MAP_FAILED"));
}

Expand Down Expand Up @@ -103,11 +103,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {

let align = this.machine.page_align();
let Some(map_length) = length.checked_next_multiple_of(this.machine.page_size) else {
this.set_last_error(this.eval_libc("EINVAL"))?;
this.set_last_error(LibcError("EINVAL"))?;
return interp_ok(this.eval_libc("MAP_FAILED"));
};
if map_length > this.target_usize_max() {
this.set_last_error(this.eval_libc("EINVAL"))?;
this.set_last_error(LibcError("EINVAL"))?;
return interp_ok(this.eval_libc("MAP_FAILED"));
}

Expand Down Expand Up @@ -141,7 +141,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
return this.set_last_error_and_return_i32(LibcError("EINVAL"));
};
if length > this.target_usize_max() {
this.set_last_error(this.eval_libc("EINVAL"))?;
this.set_last_error(LibcError("EINVAL"))?;
return interp_ok(this.eval_libc("MAP_FAILED"));
}

Expand Down

0 comments on commit c1004ff

Please sign in to comment.