Skip to content

Commit c2e71eb

Browse files
authored
winch: Fix memory.atomic.* with overflowing offsets (#12909)
* winch: Fix `memory.atomic.*` with overflowing offsets This commit fixes a spec-compliance issue with `memory.atomic.*` instructions using the Winch compiler. Specifically Winch previously added the dynamic offset to the static offset when calculating the effective address of the operation, but this addition was allowed to overflow. This meant that an operation which should trap would continue instead. The fix here is to use checked arithmetic at runtime to ensure that the address computation does not overflow. * Update test expectations
1 parent 9500c41 commit c2e71eb

6 files changed

Lines changed: 51 additions & 14 deletions

File tree

crates/test-util/src/wast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,7 @@ impl WastTest {
478478
"spec_testsuite/proposals/threads/atomic.wast",
479479
"spec_testsuite/proposals/threads/exports.wast",
480480
"spec_testsuite/proposals/threads/memory.wast",
481+
"misc_testsuite/memory64/threads.wast",
481482
];
482483

483484
if unsupported.iter().any(|part| self.path.ends_with(part)) {

tests/disas/winch/x64/atomic/notify/notify_offset.wat

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,29 @@
1212
;; movq 0x18(%r11), %r11
1313
;; addq $0x20, %r11
1414
;; cmpq %rsp, %r11
15-
;; ja 0x84
15+
;; ja 0x8a
1616
;; 1c: movq %rdi, %r14
1717
;; subq $0x10, %rsp
1818
;; movq %rdi, 8(%rsp)
1919
;; movq %rsi, (%rsp)
2020
;; movl $0xa, %eax
2121
;; movl $0, %ecx
2222
;; addq $8, %rcx
23-
;; pushq %rcx
23+
;; jb 0x8c
24+
;; 46: pushq %rcx
2425
;; subq $4, %rsp
2526
;; movl %eax, (%rsp)
2627
;; subq $4, %rsp
2728
;; movq %r14, %rdi
2829
;; movl $0, %esi
2930
;; movq 8(%rsp), %rdx
3031
;; movl 4(%rsp), %ecx
31-
;; callq 0x175
32+
;; callq 0x17d
3233
;; addq $4, %rsp
3334
;; addq $0xc, %rsp
3435
;; movq 8(%rsp), %r14
3536
;; addq $0x10, %rsp
3637
;; popq %rbp
3738
;; retq
38-
;; 84: ud2
39+
;; 8a: ud2
40+
;; 8c: ud2

tests/disas/winch/x64/atomic/wait/wait32_offset.wat

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
;; movq 0x18(%r11), %r11
1616
;; addq $0x30, %r11
1717
;; cmpq %rsp, %r11
18-
;; ja 0x91
18+
;; ja 0x97
1919
;; 1c: movq %rdi, %r14
2020
;; subq $0x10, %rsp
2121
;; movq %rdi, 8(%rsp)
@@ -24,7 +24,8 @@
2424
;; movl $0, %ecx
2525
;; movl $4, %edx
2626
;; addq $8, %rdx
27-
;; pushq %rdx
27+
;; jb 0x99
28+
;; 4d: pushq %rdx
2829
;; subq $4, %rsp
2930
;; movl %ecx, (%rsp)
3031
;; pushq %rax
@@ -34,11 +35,12 @@
3435
;; movq 0x18(%rsp), %rdx
3536
;; movl 0x14(%rsp), %ecx
3637
;; movq 0xc(%rsp), %r8
37-
;; callq 0x182
38+
;; callq 0x18a
3839
;; addq $0xc, %rsp
3940
;; addq $0x14, %rsp
4041
;; movq 8(%rsp), %r14
4142
;; addq $0x10, %rsp
4243
;; popq %rbp
4344
;; retq
44-
;; 91: ud2
45+
;; 97: ud2
46+
;; 99: ud2

tests/disas/winch/x64/atomic/wait/wait64_offset.wat

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
;; movq 0x18(%r11), %r11
1616
;; addq $0x30, %r11
1717
;; cmpq %rsp, %r11
18-
;; ja 0x89
18+
;; ja 0x8f
1919
;; 1c: movq %rdi, %r14
2020
;; subq $0x10, %rsp
2121
;; movq %rdi, 8(%rsp)
@@ -24,7 +24,8 @@
2424
;; movl $0, %ecx
2525
;; movl $4, %edx
2626
;; addq $8, %rdx
27-
;; pushq %rdx
27+
;; jb 0x91
28+
;; 4d: pushq %rdx
2829
;; pushq %rcx
2930
;; pushq %rax
3031
;; subq $8, %rsp
@@ -33,11 +34,12 @@
3334
;; movq 0x18(%rsp), %rdx
3435
;; movq 0x10(%rsp), %rcx
3536
;; movq 8(%rsp), %r8
36-
;; callq 0x17a
37+
;; callq 0x182
3738
;; addq $8, %rsp
3839
;; addq $0x18, %rsp
3940
;; movq 8(%rsp), %r14
4041
;; addq $0x10, %rsp
4142
;; popq %rbp
4243
;; retq
43-
;; 89: ud2
44+
;; 8f: ud2
45+
;; 91: ud2

tests/misc_testsuite/memory64/threads.wast

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,31 @@
8080
)
8181

8282
(assert_return (invoke "run"))
83+
84+
(module
85+
(memory i64 1 1 shared)
86+
87+
(func (export "notify_oob") (param i64) (result i32)
88+
local.get 0
89+
i32.const 1
90+
memory.atomic.notify offset=0x200
91+
)
92+
(func (export "wait32_oob") (param i64) (result i32)
93+
local.get 0
94+
i32.const 1
95+
i64.const -1
96+
memory.atomic.wait32 offset=0x200
97+
)
98+
(func (export "wait64_oob") (param i64) (result i32)
99+
local.get 0
100+
i64.const 1
101+
i64.const -1
102+
memory.atomic.wait64 offset=0x200
103+
)
104+
)
105+
(assert_trap (invoke "notify_oob" (i64.const 0xFFFF_FFFF_FFFF_FF00))
106+
"out of bounds memory access")
107+
(assert_trap (invoke "wait32_oob" (i64.const 0xFFFF_FFFF_FFFF_FF00))
108+
"out of bounds memory access")
109+
(assert_trap (invoke "wait64_oob" (i64.const 0xFFFF_FFFF_FFFF_FF00))
110+
"out of bounds memory access")

winch/codegen/src/codegen/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,11 +1478,12 @@ where
14781478
)?;
14791479

14801480
if arg.offset != 0 {
1481-
self.masm.add(
1481+
self.masm.checked_uadd(
14821482
writable!(addr.reg),
14831483
addr.reg,
14841484
RegImm::i64(arg.offset as i64),
14851485
OperandSize::S64,
1486+
TrapCode::HEAP_OUT_OF_BOUNDS,
14861487
)?;
14871488
}
14881489

@@ -1528,11 +1529,12 @@ where
15281529
)?;
15291530

15301531
if arg.offset != 0 {
1531-
self.masm.add(
1532+
self.masm.checked_uadd(
15321533
writable!(addr.reg),
15331534
addr.reg,
15341535
RegImm::i64(arg.offset as i64),
15351536
OperandSize::S64,
1537+
TrapCode::HEAP_OUT_OF_BOUNDS,
15361538
)?;
15371539
}
15381540

0 commit comments

Comments
 (0)