Skip to content

chore: crypto primitives external audit response 1#22272

Open
johnathan79717 wants to merge 1 commit intomerge-train/barretenbergfrom
jh/crypto-primitives-external-audit-response-1
Open

chore: crypto primitives external audit response 1#22272
johnathan79717 wants to merge 1 commit intomerge-train/barretenbergfrom
jh/crypto-primitives-external-audit-response-1

Conversation

@johnathan79717
Copy link
Copy Markdown
Contributor

@johnathan79717 johnathan79717 commented Apr 2, 2026

Audit Context

Addresses finding #2 from the "Aztec - Cryptographic Primitives" external audit: WASM Process DOS via Oversized Polynomial in Prover Commit Path.

In WASM builds, BB_NO_EXCEPTIONS is defined. The C++ definition of throw_or_abort_impl calls std::abort(), killing the WASM process on any error. Meanwhile, the header (throw_or_abort_impl.hpp) declares the same function as a WASM_IMPORT from JavaScript, where it throws a catchable JS Error. But the local C++ definition shadows the import, so the JS throw is never used.

Changes Made

throw_or_abort_impl.cpp: Guard out the C++ definition with #ifndef __wasm__ so the JS-provided import is used in WASM builds. The header already declares it as WASM_IMPORT("throw_or_abort_impl") with the comment "For a WASM build, this is provided by the JavaScript environment."

wasmtime.sh: Add -Wunknown-imports-trap=y so wasmtime (non-JS WASM runtime used in CI tests) stubs the import with a trap instead of failing with "unknown import". This is correct behavior: errors in wasmtime should still abort.

No TypeScript changes needed. The JS side already provides the import that throws a catchable Error with the actual error message.

Before: Any throw_or_abort in WASM calls abort_with_message() -> std::abort() -> WASM process dies, PXE crashes with no error message.
After: throw_or_abort in WASM calls the JS import which throws new Error(msg). The JS caller catches this as a normal exception. The WASM instance stays alive.

Testing

Verified with barretenberg/ts/src/bbapi/exception_handling.test.ts (full WASM build + TS test):

PASS  bbapi/exception_handling.test.js
  BBApi Exception Handling from bb.js
    ✓ should catch CRS initialization exceptions from WASM (25 ms)
    ✓ should return error message from caught exception (12 ms)

Checklist

  • Verified native build passes (ninja)
  • Verified WASM build passes (ninja barretenberg.wasm)
  • Ran bbapi_tests natively (2 passed)
  • Ran TS exception_handling.test.ts against WASM build (2 passed)

@johnathan79717 johnathan79717 added the ci-barretenberg Run all barretenberg/cpp checks. label Apr 2, 2026
@johnathan79717 johnathan79717 force-pushed the jh/crypto-primitives-external-audit-response-1 branch from ddfb651 to 1d0754e Compare April 2, 2026 14:18
@johnathan79717 johnathan79717 requested a review from ludamad April 2, 2026 14:19
@johnathan79717 johnathan79717 added ci-full Run all master checks. and removed ci-barretenberg Run all barretenberg/cpp checks. labels Apr 2, 2026
@johnathan79717 johnathan79717 marked this pull request as draft April 2, 2026 14:53
@johnathan79717 johnathan79717 removed the request for review from ludamad April 2, 2026 14:53
@johnathan79717 johnathan79717 marked this pull request as ready for review April 2, 2026 15:43
@johnathan79717 johnathan79717 force-pushed the jh/crypto-primitives-external-audit-response-1 branch from ea7899c to 4de984d Compare April 2, 2026 16:49
@johnathan79717 johnathan79717 enabled auto-merge (squash) April 2, 2026 17:00
@johnathan79717 johnathan79717 disabled auto-merge April 2, 2026 17:00
@johnathan79717 johnathan79717 force-pushed the jh/crypto-primitives-external-audit-response-1 branch 3 times, most recently from 390d74d to d6aa879 Compare April 7, 2026 12:46
@AztecBot
Copy link
Copy Markdown
Collaborator

AztecBot commented Apr 7, 2026

Flakey Tests

🤖 says: This CI run detected 1 tests that failed, but were tolerated due to a .test_patterns.yml entry.

\033FLAKED\033 (8;;http://ci.aztec-labs.com/d01f31183fcf5ab5�d01f31183fcf5ab58;;�):  yarn-project/end-to-end/scripts/run_test.sh simple src/e2e_offchain_payment.test.ts (60s) (code: 0)

@johnathan79717 johnathan79717 requested a review from ludamad April 7, 2026 13:44
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
static char last_error_message[ERROR_BUF_SIZE]; // NOLINT(cppcoreguidelines-avoid-c-arrays)
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
static size_t last_error_length = 0;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesnt feel right. this should just be stored by the JS operation that controls this maybe? we have a js callback whenever we have an error. this feels weird. why not call js when we have the error instead of giving the a way to get this later

In WASM builds, BB_NO_EXCEPTIONS is defined. The C++ definition of
throw_or_abort_impl calls std::abort(), killing the WASM process on
any error. Meanwhile, the header declares it as WASM_IMPORT from JS,
where it throws a catchable Error. But the local C++ definition
shadows the import.

Fix: guard out the C++ definition with #ifndef __wasm__ so the JS
import is used in WASM builds. For wasmtime (non-JS WASM runtime
used in CI tests), add -Wunknown-imports-trap=y so the import is
stubbed with a trap (correct behavior: errors in wasmtime should
still abort).

Before: any throw_or_abort in WASM kills the process, PXE crashes.
After: the JS caller gets a catchable Error("actual error message").
@johnathan79717 johnathan79717 force-pushed the jh/crypto-primitives-external-audit-response-1 branch from d6aa879 to 9818015 Compare April 7, 2026 17:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-full Run all master checks.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants