diff options
| author | Ralf Jung <post@ralfj.de> | 2025-06-30 08:22:51 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2025-06-30 08:22:51 +0200 |
| commit | cd971c6e1e969996a92889e26714cde45556ec87 (patch) | |
| tree | cab2320c5d2150d58b5e491fda92306d0dc94f52 /src/tools | |
| parent | 555553f0b86eccb6e9e480bd731dd6d59cb67aa0 (diff) | |
| download | rust-cd971c6e1e969996a92889e26714cde45556ec87.tar.gz rust-cd971c6e1e969996a92889e26714cde45556ec87.zip | |
linux futex: fix for val > i32::MAX
Diffstat (limited to 'src/tools')
| -rw-r--r-- | src/tools/miri/src/shims/unix/linux_like/sync.rs | 7 | ||||
| -rw-r--r-- | src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs | 5 |
2 files changed, 9 insertions, 3 deletions
diff --git a/src/tools/miri/src/shims/unix/linux_like/sync.rs b/src/tools/miri/src/shims/unix/linux_like/sync.rs index 86e8b57824c..9fad74c0241 100644 --- a/src/tools/miri/src/shims/unix/linux_like/sync.rs +++ b/src/tools/miri/src/shims/unix/linux_like/sync.rs @@ -15,12 +15,13 @@ pub fn futex<'tcx>( ) -> InterpResult<'tcx> { let [addr, op, val] = check_min_vararg_count("`syscall(SYS_futex, ...)`", varargs)?; + // See <https://man7.org/linux/man-pages/man2/futex.2.html> for docs. // The first three arguments (after the syscall number itself) are the same to all futex operations: - // (int *addr, int op, int val). + // (uint32_t *addr, int op, uint32_t val). // We checked above that these definitely exist. let addr = ecx.read_pointer(addr)?; let op = ecx.read_scalar(op)?.to_i32()?; - let val = ecx.read_scalar(val)?.to_i32()?; + let val = ecx.read_scalar(val)?.to_u32()?; // This is a vararg function so we have to bring our own type for this pointer. let addr = ecx.ptr_to_mplace(addr, ecx.machine.layouts.i32); @@ -138,7 +139,7 @@ pub fn futex<'tcx>( // It's not uncommon for `addr` to be passed as another type than `*mut i32`, such as `*const AtomicI32`. // We do an acquire read -- it only seems reasonable that if we observe a value here, we // actually establish an ordering with that value. - let futex_val = ecx.read_scalar_atomic(&addr, AtomicReadOrd::Acquire)?.to_i32()?; + let futex_val = ecx.read_scalar_atomic(&addr, AtomicReadOrd::Acquire)?.to_u32()?; if val == futex_val { // The value still matches, so we block the thread and make it wait for FUTEX_WAKE. diff --git a/src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs b/src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs index f8f1c554f0d..19d86f09595 100644 --- a/src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs +++ b/src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs @@ -33,6 +33,11 @@ fn wake_nobody() { 0, ); } + + // Wake u32::MAX waiters. + unsafe { + assert_eq!(libc::syscall(libc::SYS_futex, addr_of!(futex), libc::FUTEX_WAKE, u32::MAX), 0); + } } fn wake_dangling() { |
