Skip to content

Incorrect mutable reference handling in Brillig

Moderate
Savio-Sou published GHSA-mfqg-6wvq-m7mr May 19, 2026

Package

No package listed

Affected versions

1de115

Patched versions

1.0.0-beta.21

Description

The following code:

unconstrained fn foo(cond: bool) -> bool {
    let mut b = false;                                                                                                                                                                     
    let c = if cond { &mut b } else { &mut false };
    b = !b;                                                                                                                                                                                
    b = *c;                                                                                                                                                                                
    b
}

fn main() -> pub bool {
    let expected = comptime { unsafe { foo(true) } };                                                                                                                       
    let result = unsafe { foo(true) };                                                                                                                                      
    assert(result == expected);   
    unsafe { foo(true) }
}

fails with the assertion: comptime correctly returns true while Brillig returns false.

The issue seems to be within mem2reg_simple. It sees the following SSA:

  b3(v1: &mut u1):              // v1 = c (either v2 or a fresh alloc)
      v5 = load v2 -> u1        // load b
      v6 = not v5               // !b
      store v6 at v2            // b = !b (store 1) 
      v7 = load v1 -> u1       // *c
      store v7 at v2            // b = *c (store 2)
      return v7

and removes store 1 thinking it's dead, because the load in between them mentions v1 not v2. But v1 and v2 are actually the same pointer here when cond is true.

Seems to have been introduced in #11935

Severity

Moderate

CVE ID

No known CVE

Weaknesses

No CWEs