Skip to content

Commit a21369f

Browse files
authored
Merge pull request rust-lang#3984 from noahmbright/unix_shims
Clear `eval_libc` errors from unix shims
2 parents 340d2f7 + c1004ff commit a21369f

File tree

7 files changed

+28
-53
lines changed

7 files changed

+28
-53
lines changed

src/tools/miri/src/shims/foreign_items.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -447,8 +447,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
447447
} else {
448448
// If this does not fit in an isize, return null and, on Unix, set errno.
449449
if this.target_os_is_unix() {
450-
let einval = this.eval_libc("ENOMEM");
451-
this.set_last_error(einval)?;
450+
this.set_last_error(LibcError("ENOMEM"))?;
452451
}
453452
this.write_null(dest)?;
454453
}
@@ -464,8 +463,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
464463
} else {
465464
// On size overflow, return null and, on Unix, set errno.
466465
if this.target_os_is_unix() {
467-
let einval = this.eval_libc("ENOMEM");
468-
this.set_last_error(einval)?;
466+
this.set_last_error(LibcError("ENOMEM"))?;
469467
}
470468
this.write_null(dest)?;
471469
}
@@ -486,8 +484,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
486484
} else {
487485
// If this does not fit in an isize, return null and, on Unix, set errno.
488486
if this.target_os_is_unix() {
489-
let einval = this.eval_libc("ENOMEM");
490-
this.set_last_error(einval)?;
487+
this.set_last_error(LibcError("ENOMEM"))?;
491488
}
492489
this.write_null(dest)?;
493490
}

src/tools/miri/src/shims/time.rs

+3-9
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
8181
} else if relative_clocks.contains(&clk_id) {
8282
this.machine.clock.now().duration_since(this.machine.clock.epoch())
8383
} else {
84-
let einval = this.eval_libc("EINVAL");
85-
this.set_last_error(einval)?;
86-
return interp_ok(Scalar::from_i32(-1));
84+
return this.set_last_error_and_return_i32(LibcError("EINVAL"));
8785
};
8886

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

117113
let duration = system_time_to_duration(&SystemTime::now())?;
@@ -323,9 +319,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
323319
let duration = match this.read_timespec(&req)? {
324320
Some(duration) => duration,
325321
None => {
326-
let einval = this.eval_libc("EINVAL");
327-
this.set_last_error(einval)?;
328-
return interp_ok(Scalar::from_i32(-1));
322+
return this.set_last_error_and_return_i32(LibcError("EINVAL"));
329323
}
330324
};
331325

src/tools/miri/src/shims/unix/foreign_items.rs

+7-18
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
362362
// FreeBSD: https://man.freebsd.org/cgi/man.cgi?query=reallocarray
363363
match this.compute_size_in_bytes(Size::from_bytes(size), nmemb) {
364364
None => {
365-
let enmem = this.eval_libc("ENOMEM");
366-
this.set_last_error(enmem)?;
365+
this.set_last_error(LibcError("ENOMEM"))?;
367366
this.write_null(dest)?;
368367
}
369368
Some(len) => {
@@ -653,13 +652,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
653652
let chunk_size = CpuAffinityMask::chunk_size(this);
654653

655654
if this.ptr_is_null(mask)? {
656-
let efault = this.eval_libc("EFAULT");
657-
this.set_last_error(efault)?;
658-
this.write_int(-1, dest)?;
655+
this.set_last_error_and_return(LibcError("EFAULT"), dest)?;
659656
} else if cpusetsize == 0 || cpusetsize.checked_rem(chunk_size).unwrap() != 0 {
660657
// we only copy whole chunks of size_of::<c_ulong>()
661-
this.set_last_error(LibcError("EINVAL"))?;
662-
this.write_int(-1, dest)?;
658+
this.set_last_error_and_return(LibcError("EINVAL"), dest)?;
663659
} else if let Some(cpuset) = this.machine.thread_cpu_affinity.get(&thread_id) {
664660
let cpuset = cpuset.clone();
665661
// we only copy whole chunks of size_of::<c_ulong>()
@@ -668,9 +664,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
668664
this.write_null(dest)?;
669665
} else {
670666
// The thread whose ID is pid could not be found
671-
let esrch = this.eval_libc("ESRCH");
672-
this.set_last_error(esrch)?;
673-
this.write_int(-1, dest)?;
667+
this.set_last_error_and_return(LibcError("ESRCH"), dest)?;
674668
}
675669
}
676670
"sched_setaffinity" => {
@@ -695,9 +689,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
695689
};
696690

697691
if this.ptr_is_null(mask)? {
698-
let efault = this.eval_libc("EFAULT");
699-
this.set_last_error(efault)?;
700-
this.write_int(-1, dest)?;
692+
this.set_last_error_and_return(LibcError("EFAULT"), dest)?;
701693
} else {
702694
// NOTE: cpusetsize might be smaller than `CpuAffinityMask::CPU_MASK_BYTES`.
703695
// Any unspecified bytes are treated as zero here (none of the CPUs are configured).
@@ -713,8 +705,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
713705
}
714706
None => {
715707
// The intersection between the mask and the available CPUs was empty.
716-
this.set_last_error(LibcError("EINVAL"))?;
717-
this.write_int(-1, dest)?;
708+
this.set_last_error_and_return(LibcError("EINVAL"), dest)?;
718709
}
719710
}
720711
}
@@ -770,9 +761,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
770761
// macOS: https://keith.github.io/xcode-man-pages/getentropy.2.html
771762
// Solaris/Illumos: https://illumos.org/man/3C/getentropy
772763
if bufsize > 256 {
773-
let err = this.eval_libc("EIO");
774-
this.set_last_error(err)?;
775-
this.write_int(-1, dest)?;
764+
this.set_last_error_and_return(LibcError("EIO"), dest)?;
776765
} else {
777766
this.gen_random(buf, bufsize)?;
778767
this.write_null(dest)?;

src/tools/miri/src/shims/unix/fs.rs

+7-10
Original file line numberDiff line numberDiff line change
@@ -787,13 +787,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
787787
let ecode = if path.is_absolute() || dirfd == this.eval_libc_i32("AT_FDCWD") {
788788
// since `path` is provided, either absolute or
789789
// relative to CWD, `EACCES` is the most relevant.
790-
this.eval_libc("EACCES")
790+
LibcError("EACCES")
791791
} else {
792792
// `dirfd` is set to target file, and `path` is empty
793793
// (or we would have hit the `throw_unsup_format`
794794
// above). `EACCES` would violate the spec.
795795
assert!(empty_path_flag);
796-
this.eval_libc("EBADF")
796+
LibcError("EBADF")
797797
};
798798
return this.set_last_error_and_return_i32(ecode);
799799
}
@@ -1031,8 +1031,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
10311031
// Reject if isolation is enabled.
10321032
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
10331033
this.reject_in_isolation("`readdir`", reject_with)?;
1034-
let eacc = this.eval_libc("EBADF");
1035-
this.set_last_error(eacc)?;
1034+
this.set_last_error(LibcError("EBADF"))?;
10361035
return interp_ok(Scalar::null_ptr(this));
10371036
}
10381037

@@ -1449,11 +1448,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
14491448
if fd.is_tty(this.machine.communicate()) {
14501449
return interp_ok(Scalar::from_i32(1));
14511450
} else {
1452-
this.eval_libc("ENOTTY")
1451+
LibcError("ENOTTY")
14531452
}
14541453
} else {
14551454
// FD does not exist
1456-
this.eval_libc("EBADF")
1455+
LibcError("EBADF")
14571456
};
14581457
this.set_last_error(error)?;
14591458
interp_ok(Scalar::from_i32(0))
@@ -1473,8 +1472,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
14731472
// Reject if isolation is enabled.
14741473
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
14751474
this.reject_in_isolation("`realpath`", reject_with)?;
1476-
let eacc = this.eval_libc("EACCES");
1477-
this.set_last_error(eacc)?;
1475+
this.set_last_error(LibcError("EACCES"))?;
14781476
return interp_ok(Scalar::from_target_usize(0, this));
14791477
}
14801478

@@ -1504,8 +1502,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
15041502
// Note that we do not explicitly handle `FILENAME_MAX`
15051503
// (different from `PATH_MAX` above) as it is Linux-specific and
15061504
// seems like a bit of a mess anyway: <https://eklitzke.org/path-max-is-tricky>.
1507-
let enametoolong = this.eval_libc("ENAMETOOLONG");
1508-
this.set_last_error(enametoolong)?;
1505+
this.set_last_error(LibcError("ENAMETOOLONG"))?;
15091506
return interp_ok(Scalar::from_target_usize(0, this));
15101507
}
15111508
processed_ptr

src/tools/miri/src/shims/unix/linux/mem.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
2424
// old_address must be a multiple of the page size
2525
#[allow(clippy::arithmetic_side_effects)] // PAGE_SIZE is nonzero
2626
if old_address.addr().bytes() % this.machine.page_size != 0 || new_size == 0 {
27-
this.set_last_error(this.eval_libc("EINVAL"))?;
27+
this.set_last_error(LibcError("EINVAL"))?;
2828
return interp_ok(this.eval_libc("MAP_FAILED"));
2929
}
3030

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

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

src/tools/miri/src/shims/unix/linux/sync.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,7 @@ pub fn futex<'tcx>(
158158
} else {
159159
// The futex value doesn't match the expected value, so we return failure
160160
// right away without sleeping: -1 and errno set to EAGAIN.
161-
let eagain = this.eval_libc("EAGAIN");
162-
this.set_last_error(eagain)?;
163-
this.write_scalar(Scalar::from_target_isize(-1, this), dest)?;
161+
this.set_last_error_and_return(LibcError("EAGAIN"), dest)?;
164162
}
165163
}
166164
// FUTEX_WAKE: (int *addr, int op = FUTEX_WAKE, int val)

src/tools/miri/src/shims/unix/mem.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
5757

5858
// First, we do some basic argument validation as required by mmap
5959
if (flags & (map_private | map_shared)).count_ones() != 1 {
60-
this.set_last_error(this.eval_libc("EINVAL"))?;
60+
this.set_last_error(LibcError("EINVAL"))?;
6161
return interp_ok(this.eval_libc("MAP_FAILED"));
6262
}
6363
if length == 0 {
64-
this.set_last_error(this.eval_libc("EINVAL"))?;
64+
this.set_last_error(LibcError("EINVAL"))?;
6565
return interp_ok(this.eval_libc("MAP_FAILED"));
6666
}
6767

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

104104
let align = this.machine.page_align();
105105
let Some(map_length) = length.checked_next_multiple_of(this.machine.page_size) else {
106-
this.set_last_error(this.eval_libc("EINVAL"))?;
106+
this.set_last_error(LibcError("EINVAL"))?;
107107
return interp_ok(this.eval_libc("MAP_FAILED"));
108108
};
109109
if map_length > this.target_usize_max() {
110-
this.set_last_error(this.eval_libc("EINVAL"))?;
110+
this.set_last_error(LibcError("EINVAL"))?;
111111
return interp_ok(this.eval_libc("MAP_FAILED"));
112112
}
113113

@@ -141,7 +141,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
141141
return this.set_last_error_and_return_i32(LibcError("EINVAL"));
142142
};
143143
if length > this.target_usize_max() {
144-
this.set_last_error(this.eval_libc("EINVAL"))?;
144+
this.set_last_error(LibcError("EINVAL"))?;
145145
return interp_ok(this.eval_libc("MAP_FAILED"));
146146
}
147147

0 commit comments

Comments
 (0)