Commit dfbe997
authored
x64: Add bitwidth-specific newtypes for registers. (#13184)
This change addresses the kind of lowering mismatch that we saw in
CVE-2026-24116 ([advisory]): a case where an instruction lowering
reasons about a narrower value (e.g. a scalar `f64`) in a wider register
(e.g. a 128-bit XMM), and implicit conversions cause load-sinking to
happen in a way that leads to a larger-than-expected load from memory.
Background: in Cranelift in general, we have an "upper bits undefined"
invariant. That is, a 32/64-bit FP value can live in a 128-bit XMM
register, or 8/16/32-bit integer can live in a 64-bit GPR, with no
problem. The instruction lowering sequences generally deal fine with
this: e.g., an `add` instruction doesn't care what is in the upper bits
(garbage in, garbage out, and carry only flows from lower to upper, not
the other way).
However, load-sinking, designed to be as "automatic" as possible to
apply in all of the places where it is applicable, throws a wrench into
this: because we don't make a distinction about how large the actual
operand is, and many layers of the ISLE deal only in register-related
operand types (`RegMem`, `GprMem` or `XmmMem`), we can get an implicit
load of the *entire* register width when we had started with a
narrowly-typed value. This is a miscompile that can become serious if
paired with a user of Cranelift (e.g. Wasmtime) that relies on certain
characteristics of out-of-bound accesses to maintain a sandbox.
In this PR, we take the approach discussed in #12477: we add newtypes
for all *specific* bit-widths of operand, to make the distinction solely
at metacopmilation time (i.e., when the ISLE DSL itself is typechecked)
in the lowering patterns. The expected widths flow upward from the
auto-generated instruction constructors in the assembler layer. We use
specific types almost universally; in a few cases where helpers do a
dynamic dispatch on type, we have specific generic-to-specific-width
converters that *also* take the `ty` and assert that it has the correct
width. Then, finally and most importantly, the auto-conversions for load
sinking will only work (and will release-assert otherwise) if the
type-width of the corresponding `Value` matches.
As a result of doing this large refactor, three separate bugs in
sunk-load width were found; see the new filetests. They are:
- `bitselect` on scalar f32/f64 args could sink a load, and would use a
SIMD instruction that could fold a load and do a 128-bit load. (Wasm
lowering only uses `bitselect` with 128-bit args.)
- `swiden_low` and `uwiden_low` could fold a 128-bit load and do a
64-bit load (i.e., could *narrow* the memory op) because the SSE4.1
instruction takes a 64-bit source operand. (Wasm lowering inserts
bitcasts that prevent load-sinking in this case.)
- `fcvt_from_sint` could likewise turn a 128-bit load into a 64-bit
load. (Wasm lowering likewise foils the bug with bitcasts.)
I verified that none of them are reachable from Wasm, fortunately, so we
don't have a repeat of the above CVE.
Fixes #12477.
[advisory]:
GHSA-vc8c-j3xm-xj731 parent 599d821 commit dfbe997
9 files changed
Lines changed: 2712 additions & 533 deletions
File tree
- cranelift
- codegen
- meta/src
- src/isa/x64
- inst
- lower
- filetests/filetests/isa/x64
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
22 | 25 | | |
23 | 26 | | |
24 | 27 | | |
| |||
32 | 35 | | |
33 | 36 | | |
34 | 37 | | |
35 | | - | |
| 38 | + | |
| 39 | + | |
36 | 40 | | |
37 | 41 | | |
38 | 42 | | |
| |||
243 | 247 | | |
244 | 248 | | |
245 | 249 | | |
246 | | - | |
| 250 | + | |
| 251 | + | |
247 | 252 | | |
248 | 253 | | |
249 | 254 | | |
| |||
265 | 270 | | |
266 | 271 | | |
267 | 272 | | |
268 | | - | |
| 273 | + | |
| 274 | + | |
269 | 275 | | |
270 | 276 | | |
271 | 277 | | |
| |||
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
27 | 35 | | |
28 | 36 | | |
29 | 37 | | |
30 | 38 | | |
31 | 39 | | |
32 | | - | |
33 | | - | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
34 | 46 | | |
35 | 47 | | |
36 | 48 | | |
| |||
146 | 158 | | |
147 | 159 | | |
148 | 160 | | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
149 | 168 | | |
150 | 169 | | |
151 | 170 | | |
| |||
227 | 246 | | |
228 | 247 | | |
229 | 248 | | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
230 | 256 | | |
231 | 257 | | |
232 | 258 | | |
| |||
294 | 320 | | |
295 | 321 | | |
296 | 322 | | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
297 | 327 | | |
298 | 328 | | |
299 | 329 | | |
300 | 330 | | |
301 | | - | |
302 | | - | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
303 | 341 | | |
304 | 342 | | |
305 | 343 | | |
| |||
324 | 362 | | |
325 | 363 | | |
326 | 364 | | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
327 | 369 | | |
328 | 370 | | |
329 | 371 | | |
330 | 372 | | |
331 | | - | |
332 | | - | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
333 | 397 | | |
334 | 398 | | |
335 | 399 | | |
| |||
0 commit comments