WebAssembly / WebAssembly/wabt

Zero-sized literal output buffers cause out-of-bounds access

Open Beginner friendly
#2,851 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C++
Stars
8.1k
Forks
827
Avg merge
4d 6h
Merged PRs (30d)
18

Description

Description and impact

The shared implementation behind WriteFloatHex() and WriteDoubleHex(), as well as WriteUint128(), subtracts one from the output size while truncating a formatted value. When a caller supplies size == 0, that subtraction wraps to SIZE_MAX, which leads to an invalid copy length or array index.

With an AddressSanitizer and UndefinedBehaviorSanitizer build, the float and double wrappers abort with AddressSanitizer: negative-size-param: (size=-1), while WriteUint128() aborts on an index of 18446744073709551615. Without sanitizer checks, these accesses are undefined behavior and can crash a process using libwabt.

Reproduction

Minimal library-level reproduction; run the program once with each of the three calls enabled individually:

#include "wabt/literal.h"

int main() {
  char output = 'x';
  wabt::WriteFloatHex(&output, 0, 0);
  // wabt::WriteDoubleHex(&output, 0, 0);
  // wabt::WriteUint128(&output, 0, {0, 0, 0, 0});
}

Affected surface

The affected surface is the public libwabt functions WriteFloatHex(), WriteDoubleHex(), and WriteUint128(). Their public declarations do not document a size > 0 precondition. I did not find a bundled CLI call site that supplies a zero-sized buffer; the current in-tree call sites use nonzero fixed-size buffers.

Required WebAssembly features

None. No --enable flag is needed.

Candidate fix and validation

I have a small fix that returns before accessing the output for size == 0, plus GoogleTests covering all three public functions in the regular unit-test target. The two focused regressions, all 137 WABT unit tests, a three-function ASan/UBSan harness, and the full WERROR=ON CMake build and check target pass on macOS with AppleClang.

I did not run the exhaustive 32-bit hexfloat_test input space.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the public declarations in wabt/literal.h and the shared implementation used by WriteFloatHex(), WriteDoubleHex(), and WriteUint128(). Add zero-size regression coverage in the regular GoogleTest target, then run the focused tests, all 137 WABT unit tests, and the WERROR=ON CMake check target; done means none of the three functions accesses the output for a zero-sized buffer.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
security, tooling
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.