Skip to content

Commit efc63a4

Browse files
authored
Merge pull request #4429 from RalfJung/futex-val-too-big
linux futex: fix for val > i32::MAX
2 parents 0555ada + e98889c commit efc63a4

File tree

2 files changed

+9
-3
lines changed

2 files changed

+9
-3
lines changed

src/shims/unix/linux_like/sync.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@ pub fn futex<'tcx>(
1515
) -> InterpResult<'tcx> {
1616
let [addr, op, val] = check_min_vararg_count("`syscall(SYS_futex, ...)`", varargs)?;
1717

18+
// See <https://man7.org/linux/man-pages/man2/futex.2.html> for docs.
1819
// The first three arguments (after the syscall number itself) are the same to all futex operations:
19-
// (int *addr, int op, int val).
20+
// (uint32_t *addr, int op, uint32_t val).
2021
// We checked above that these definitely exist.
2122
let addr = ecx.read_pointer(addr)?;
2223
let op = ecx.read_scalar(op)?.to_i32()?;
23-
let val = ecx.read_scalar(val)?.to_i32()?;
24+
let val = ecx.read_scalar(val)?.to_u32()?;
2425

2526
// This is a vararg function so we have to bring our own type for this pointer.
2627
let addr = ecx.ptr_to_mplace(addr, ecx.machine.layouts.i32);
@@ -138,7 +139,7 @@ pub fn futex<'tcx>(
138139
// It's not uncommon for `addr` to be passed as another type than `*mut i32`, such as `*const AtomicI32`.
139140
// We do an acquire read -- it only seems reasonable that if we observe a value here, we
140141
// actually establish an ordering with that value.
141-
let futex_val = ecx.read_scalar_atomic(&addr, AtomicReadOrd::Acquire)?.to_i32()?;
142+
let futex_val = ecx.read_scalar_atomic(&addr, AtomicReadOrd::Acquire)?.to_u32()?;
142143
if val == futex_val {
143144
// The value still matches, so we block the thread and make it wait for FUTEX_WAKE.
144145

tests/pass-dep/concurrency/linux-futex.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ fn wake_nobody() {
3333
0,
3434
);
3535
}
36+
37+
// Wake u32::MAX waiters.
38+
unsafe {
39+
assert_eq!(libc::syscall(libc::SYS_futex, addr_of!(futex), libc::FUTEX_WAKE, u32::MAX), 0);
40+
}
3641
}
3742

3843
fn wake_dangling() {

0 commit comments

Comments
 (0)