WebAssembly (WASM) interpreters are becoming increasingly popular for running code safely in browsers and other environments. However, software vulnerabilities still sneak in—like one found in the very core of WASM tooling. In this post, we’ll break down CVE-2022-43282, an out-of-bounds read discovered in the wasm-interp tool (version 1..29), show you what went wrong, and explore how an attacker could leverage this bug.

What is CVE-2022-43282?

CVE-2022-43282 is a vulnerability in wasm-interp, the official WebAssembly interpreter from the WebAssembly Binary Toolkit. It’s triggered by an out-of-bounds read in the function OnReturnCallIndirectExpr->GetReturnCallDropKeepCount, due to improper bounds checking. This can lead to a denial of service (crash) or potentially information leaks.

Root Cause: Walking Off the Array

Let’s break down what’s happening under the hood with a simplified look at the code.

Suppose the relevant code looks something like this (for explanation)

// Pseudocode, simplified for clarity

class OnReturnCallIndirectExpr {
public:
    std::vector<uint32_t> counts;  // Stores count values

    uint32_t GetReturnCallDropKeepCount(size_t idx) {
        // Bug: Missing bounds check on 'idx'
        return counts[idx];  // <-- May read beyond the array!
    }
};

The function GetReturnCallDropKeepCount returns a value at a specified index from a vector or array. However, it doesn’t check if idx is within the valid range. If an attacker can craft input to make idx out of range, wasm-interp will access memory it didn’t intend to, crashing or even revealing information.

Here’s an example of how you might trigger the bug

1. Craft a malicious WASM binary: Create a .wasm file that, when parsed, causes interpreter code to invoke GetReturnCallDropKeepCount with a large idx value.

Execute the interpreter: Run wasm-interp with the malicious file as input.

You can use wabt’s own tools or write minimal raw bytes. For example, consider this shell snippet:

# Place your malicious wasm binary in bad.wasm
./wasm-interp bad.wasm

And a fuzzed/edited WASM file that will hit the overflow. Tools like AFL++ can automate finding these crashes.

Why Does This Matter?

Out-of-bounds reads are classic vulnerabilities. Even if they only crash the process today, they can be the first step toward more serious exploits like memory leaks or code execution.

- If wasm-interp is used as part of a chain (e.g., web server handling uploads): Persistent attackers could try to crash or leak information.

References & Further Reading

- CVE page for CVE-2022-43282 (NVD)
- Original Issue Report on GitHub
- WebAssembly Binary Toolkit (wabt) main GitHub repo
- Wasm-interp Documentation
- Understanding Out-of-Bounds Vulnerabilities - OWASP

Simple fix: Add a bounds check before accessing the array

uint32_t GetReturnCallDropKeepCount(size_t idx) {
    if (idx >= counts.size()) {
        // Handle error: idx out of range
        throw std::out_of_range("idx out of bounds in GetReturnCallDropKeepCount");
    }
    return counts[idx];
}

The patch inserts a check before reading from counts.

Fuzzing and code audit are musts for any parsing or interpreter code.

Keep your toolchains updated, watch for CVEs, and audit code that handles binary input!

Timeline

Published on: 10/28/2022 21:15:00 UTC
Last modified on: 11/01/2022 16:59:00 UTC