WebAssembly / WebAssembly/wabt
Zero-sized literal output buffers cause out-of-bounds access
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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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