Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cranelift: ty_smin/smax/umax/mask panic on i128 #8690

Closed
jameysharp opened this issue May 24, 2024 · 3 comments · Fixed by #8707
Closed

cranelift: ty_smin/smax/umax/mask panic on i128 #8690

jameysharp opened this issue May 24, 2024 · 3 comments · Fixed by #8707
Labels
bug Incorrect behavior in the current implementation that needs fixing fuzz-bug Bugs found by a fuzzer

Comments

@jameysharp
Copy link
Contributor

OSS-Fuzz reported this as https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=69209. I've minimized the test case and identified several related panics, all with the message "unimplemented for > 64 bits".

This is not a security issue according to Wasmtime's security policy because it's a panic at compile time. It also shouldn't be reachable from Wasmtime today, only other Cranelift frontends.

Minimized CLIF
test compile
set opt_level=speed
target x86_64

function %slt() system_v {
block0:
    v0 = iconst.i64 0
    v1 = uextend.i128 v0
    v2 = icmp slt v1, v1
    return
}

function %ult() system_v { 
block0:
    v0 = iconst.i64 0 
    v1 = uextend.i128 v0
    v2 = icmp ult v1, v1
    return
}

The original fuzzbug, and my %slt function above, hit this panic in ty_smin:

let shift = 64_u64
.checked_sub(ty_bits.into())
.expect("unimplemented for > 64 bits");

I believe the optimization rule which invoked ty_smin is here:

;; slt(x, SMIN) == false.
(rule (simplify (slt (fits_in_64 (ty_int bty)) x smin @ (iconst_u cty y)))
(if-let $true (u64_eq y (ty_smin cty)))
(subsume (iconst_u bty 0)))

There are similar rules for ult exercised by my %ult function above. They call ty_umax, which calls ty_mask, which has essentially the same panic.

There are also similar rules for slt which would hit an equivalent panic in ty_smax, but I can't exercise them because ISLE is choosing to call ty_smin first which then panics.

I believe these panics are only being exposed now because #8686 allowed these rules to match i128 constants when they couldn't before. The rules should still fail to match because of the fits_in_64 constraint on the other type in the pattern. However, ISLE does not guarantee anything about what order constructors and extractors will be evaluated in except for data dependencies. So that fits_in_64 guard isn't sufficient to ensure that ty_smin won't be called.

One fix that I've verified works for the %slt test case:

  • add the partial keyword to (decl pure ty_smin ...) and similarly for ty_smax,
  • make the corresponding Rust functions return Option,
  • use ? instead of .expect() when .checked_sub() fails.

However I ran out of energy when I looked at doing the same for ty_umax, which requires doing it for ty_mask, which is called from Rust in a lot of places.

cc: @scottmcm

@jameysharp jameysharp added bug Incorrect behavior in the current implementation that needs fixing fuzz-bug Bugs found by a fuzzer labels May 24, 2024
@alexcrichton
Copy link
Member

Would it perhaps make sense to revert #8686 while a "true fix" is found in the meantime?

@scottmcm
Copy link
Contributor

From my side, feel free to revert my PR for now. I likely won't be able to look at fixing this in the short term.

@alexcrichton
Copy link
Member

I've posted #8707 to revert the original PR and included this issue's test cases as well so a re-landing will be sure to trigger the new test case too.

github-merge-queue bot pushed a commit that referenced this issue May 30, 2024
…" (#8707)

* Revert "Use `[su]extend_maybe` in the `iconst_[su]` extractors (#8686)"

This reverts commit 66f499f.

* Add in failing tests from #8690
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Incorrect behavior in the current implementation that needs fixing fuzz-bug Bugs found by a fuzzer
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants