From 79ae6f27da94d52b789ff6cace15a0b9bd4aa9dd Mon Sep 17 00:00:00 2001 From: retoor Date: Tue, 27 Oct 2026 19:03:32 +0100 Subject: [PATCH] cpp-safety: safe-C++ playbook, fix a second UB, and a sanitizer net Response to incident WA-2026-10-27 (the std::vector max_size() crash). Deep research archived under research/safe-cpp-practices (8 Tier 1, 37 Tier 2, 2 conclusions) on production-safe C++ that keeps development speed: OpenSSF compiler hardening, the C++ Core Guidelines bounds profile, integer-overflow practice, libFuzzer/sanitizer CI, the sanitizer overhead ladder, clang-tidy ratchets. The research prescribed an ASan+UBSan+_GLIBCXX_ASSERTIONS build of the parsers. Standing it up immediately caught a second, independent undefined-behavior bug that two manual reviews had missed: a protobuf varint loop that shifted by up to 70 bits (shift >= 64 is UB) on malformed input. Fixed and guarded by a deterministic test and the sanitizer net. - src/whatsapp/wa_proto.cpp: guard the wire-0 varint shift (the UB). - tests/whatsapp_test.cpp: add an overlong-varint hostile case. - tools/san-whatsapp.sh: the standing sanitizer net for detz::wa parsers. - WaClient frame capture: a frame that fails to decode/dispatch has its exact bytes recorded to /whatsapp/last-error.log (bounded), so the still unreproduced live failure becomes a one-paste deterministic fix. Wired from the wizard and the whatsapp_send tool. - docs/cpp-safety.md: the project-wide playbook and design decisions (four layers: overflow-safe checked-reader parsing, cheap release hardening, the sanitizer test net, capture). docs/whatsapp.md section 13.6 records the follow-up and the honest open item. AGENTS.md makes it a standing rule; cap.md and mcp.md inherit it for their wire parsers. Verified: build, whatsapp_test (incl. hostile+fuzz), make lint, and tools/san-whatsapp.sh all green; research audit PASS. Co-Authored-By: Claude Opus 4.8 --- research/INDEX.md | 13 ++--- .../aws-detector-intoverflow.md | 28 ++++++++++ .../safe-cpp-practices/bitcoinsv-clangtidy.md | 28 ++++++++++ .../cfncloud-stack-protection.md | 28 ++++++++++ .../clang-tidy-fix-bench.md | 28 ++++++++++ .../clang-tidy-production-ratchet.md | 50 ++++++++++++++++++ .../safe-cpp-practices/conan-sanitizers.md | 28 ++++++++++ .../conclusions/detz-safe-cpp-playbook.md | 49 ++++++++++++++++++ .../incident-wa-length-error-root-cause.md | 46 +++++++++++++++++ .../cpp-core-guidelines-bounds-gsl.md | 50 ++++++++++++++++++ .../safe-cpp-practices/cppreference-span.md | 28 ++++++++++ .../safe-cpp-practices/daphne-sanitizer-ci.md | 28 ++++++++++ .../debuggai-fuzzing-2025.md | 28 ++++++++++ .../eigen-clangtidy-advisory.md | 28 ++++++++++ research/safe-cpp-practices/embedonix-span.md | 28 ++++++++++ .../safe-cpp-practices/finos-cg-slides.md | 28 ++++++++++ research/safe-cpp-practices/gcc-fhardened.md | 49 ++++++++++++++++++ .../safe-cpp-practices/github-gsl-lite.md | 28 ++++++++++ .../safe-cpp-practices/github-imshark-fuzz.md | 28 ++++++++++ .../github-microsoft-gsl.md | 28 ++++++++++ .../guzenfeld-lowlatency.md | 28 ++++++++++ .../hn-hardening-overhead.md | 28 ++++++++++ .../integer-overflow-size-checks.md | 50 ++++++++++++++++++ .../libfuzzer-sanitizer-ci.md | 50 ++++++++++++++++++ .../meetingcpp-sanitizers-2025.md | 28 ++++++++++ .../safe-cpp-practices/microsoft-gsl-3-0.md | 28 ++++++++++ .../safe-cpp-practices/modernescpp-bounds.md | 28 ++++++++++ .../safe-cpp-practices/modernescpp-gsl.md | 28 ++++++++++ research/safe-cpp-practices/ms-ntintsafe.md | 28 ++++++++++ research/safe-cpp-practices/msvc-c26472.md | 28 ++++++++++ .../safe-cpp-practices/nhimg-fuzzing-guide.md | 28 ++++++++++ .../safe-cpp-practices/nhimg-secure-coding.md | 28 ++++++++++ .../offensive360-intoverflow.md | 28 ++++++++++ .../office-cpp-guidelines.md | 28 ++++++++++ .../openssf-compiler-hardening-guide.md | 51 +++++++++++++++++++ .../orbis-image-overflow.md | 28 ++++++++++ .../safe-cpp-practices/ossf-hardening-md.md | 28 ++++++++++ .../pardisp-clang-sanitizers.md | 28 ++++++++++ .../platformio-clangtidy.md | 28 ++++++++++ .../safe-cpp-practices/redhat-gcc-flags.md | 28 ++++++++++ .../sanitizer-overhead-maturity-ladder.md | 50 ++++++++++++++++++ .../safe-cpp-practices/sanitizers-handbook.md | 28 ++++++++++ .../shipsoft-clangtidy-ratchet.md | 28 ++++++++++ .../safe-cpp-practices/sqlpey-intoverflow.md | 28 ++++++++++ .../std-span-no-default-bounds-check.md | 49 ++++++++++++++++++ research/safe-cpp-practices/tcbrindle-span.md | 28 ++++++++++ .../trailofbits-libfuzzer-skill.md | 28 ++++++++++ .../safe-cpp-practices/yunolay-fuzzing.md | 28 ++++++++++ taicpp/docs/cap.md | 2 + taicpp/docs/mcp.md | 2 + taicpp/docs/whatsapp.md | 30 +++++++++++ taicpp/src/agent/tools_ops.cpp | 1 + taicpp/src/whatsapp/wa_client.cpp | 17 +++++++ taicpp/src/whatsapp/wa_client.h | 9 ++++ taicpp/src/whatsapp/wa_proto.cpp | 1 + taicpp/src/whatsapp/wa_wizard.cpp | 1 + taicpp/tests/whatsapp_test.cpp | 16 ++++++ taicpp/tools/san-whatsapp.sh | 31 +++++++++++ 58 files changed, 1647 insertions(+), 6 deletions(-) create mode 100644 research/safe-cpp-practices/aws-detector-intoverflow.md create mode 100644 research/safe-cpp-practices/bitcoinsv-clangtidy.md create mode 100644 research/safe-cpp-practices/cfncloud-stack-protection.md create mode 100644 research/safe-cpp-practices/clang-tidy-fix-bench.md create mode 100644 research/safe-cpp-practices/clang-tidy-production-ratchet.md create mode 100644 research/safe-cpp-practices/conan-sanitizers.md create mode 100644 research/safe-cpp-practices/conclusions/detz-safe-cpp-playbook.md create mode 100644 research/safe-cpp-practices/conclusions/incident-wa-length-error-root-cause.md create mode 100644 research/safe-cpp-practices/cpp-core-guidelines-bounds-gsl.md create mode 100644 research/safe-cpp-practices/cppreference-span.md create mode 100644 research/safe-cpp-practices/daphne-sanitizer-ci.md create mode 100644 research/safe-cpp-practices/debuggai-fuzzing-2025.md create mode 100644 research/safe-cpp-practices/eigen-clangtidy-advisory.md create mode 100644 research/safe-cpp-practices/embedonix-span.md create mode 100644 research/safe-cpp-practices/finos-cg-slides.md create mode 100644 research/safe-cpp-practices/gcc-fhardened.md create mode 100644 research/safe-cpp-practices/github-gsl-lite.md create mode 100644 research/safe-cpp-practices/github-imshark-fuzz.md create mode 100644 research/safe-cpp-practices/github-microsoft-gsl.md create mode 100644 research/safe-cpp-practices/guzenfeld-lowlatency.md create mode 100644 research/safe-cpp-practices/hn-hardening-overhead.md create mode 100644 research/safe-cpp-practices/integer-overflow-size-checks.md create mode 100644 research/safe-cpp-practices/libfuzzer-sanitizer-ci.md create mode 100644 research/safe-cpp-practices/meetingcpp-sanitizers-2025.md create mode 100644 research/safe-cpp-practices/microsoft-gsl-3-0.md create mode 100644 research/safe-cpp-practices/modernescpp-bounds.md create mode 100644 research/safe-cpp-practices/modernescpp-gsl.md create mode 100644 research/safe-cpp-practices/ms-ntintsafe.md create mode 100644 research/safe-cpp-practices/msvc-c26472.md create mode 100644 research/safe-cpp-practices/nhimg-fuzzing-guide.md create mode 100644 research/safe-cpp-practices/nhimg-secure-coding.md create mode 100644 research/safe-cpp-practices/offensive360-intoverflow.md create mode 100644 research/safe-cpp-practices/office-cpp-guidelines.md create mode 100644 research/safe-cpp-practices/openssf-compiler-hardening-guide.md create mode 100644 research/safe-cpp-practices/orbis-image-overflow.md create mode 100644 research/safe-cpp-practices/ossf-hardening-md.md create mode 100644 research/safe-cpp-practices/pardisp-clang-sanitizers.md create mode 100644 research/safe-cpp-practices/platformio-clangtidy.md create mode 100644 research/safe-cpp-practices/redhat-gcc-flags.md create mode 100644 research/safe-cpp-practices/sanitizer-overhead-maturity-ladder.md create mode 100644 research/safe-cpp-practices/sanitizers-handbook.md create mode 100644 research/safe-cpp-practices/shipsoft-clangtidy-ratchet.md create mode 100644 research/safe-cpp-practices/sqlpey-intoverflow.md create mode 100644 research/safe-cpp-practices/std-span-no-default-bounds-check.md create mode 100644 research/safe-cpp-practices/tcbrindle-span.md create mode 100644 research/safe-cpp-practices/trailofbits-libfuzzer-skill.md create mode 100644 research/safe-cpp-practices/yunolay-fuzzing.md create mode 100755 taicpp/tools/san-whatsapp.sh diff --git a/research/INDEX.md b/research/INDEX.md index 2443530..0e4e388 100644 --- a/research/INDEX.md +++ b/research/INDEX.md @@ -6,11 +6,11 @@ | Metric | Value | |---|---| -| Subjects | 17 | -| Total source documents | 1136 | -| — Tier 1 (Source Dossier, independently analyzed) | 301 | -| — Tier 2 (Source Citation Card, listed only) | 835 | -| Total conclusion documents | 43 | +| Subjects | 18 | +| Total source documents | 1181 | +| — Tier 1 (Source Dossier, independently analyzed) | 309 | +| — Tier 2 (Source Citation Card, listed only) | 872 | +| Total conclusion documents | 45 | | Archive opened | 2026-10-09 | | Last updated | 2026-10-27 | @@ -34,6 +34,7 @@ | [`mcp-client-support`](mcp-client-support/) | 106 (38 / 68) | 3 | 2026-10-18 | 2026-10-18 | Designing tai's MCP client: wire spec (stdio + Streamable HTTP on the 2025-11-25 baseline), pasted-config/GitHub-URL resolver, and the trust/approval model; decided minimal stdlib client, normalizer plus resolver agent, untrusted-until-consent with description pinning, no OAuth in v1, nothing built yet | | [`fuzzy-matching-selectors`](fuzzy-matching-selectors/) | 65 (12 / 53) | 2 | 2026-10-25 | 2026-10-25 | Making `@agent` / `@model` mentions pick the most related candidate: fzf/fzy/Sublime/clangd subsequence scoring, Damerau-Levenshtein, pg_trgm, RapidFuzz WRatio, difflib, CPython suggestions surveyed; decided one generic `FuzzyMatcher` (four signals, deterministic ties, floor 0.3 across agents and models) and implemented it the same day | | [`whatsapp-automation`](whatsapp-automation/) | 70 (9 / 61) | 3 | 2026-10-27 | 2026-10-27 | Making detz send WhatsApp messages from C++ on a personal number: no native Python library exists (neonize is whatsmeow over ctypes, yowsup is dead), no browser needed, decided a native C++ transpile from wa-go (MIT, golden vectors) with whatsmeow as referee, GPL libsignal avoided, plus a whatsapp-mcp shortcut; specified in taicpp/docs/whatsapp.md, nothing built | +| [`safe-cpp-practices`](safe-cpp-practices/) | 45 (8 / 37) | 2 | 2026-10-27 | 2026-10-27 | How to write safe, fast, OO production C++ while keeping dev speed, triggered by a `std::vector larger than max_size()` crash in the WhatsApp wire parser; decided a four-layer playbook (overflow-safe checked-reader parsing, cheap always-on release hardening, an ASan+UBSan+_GLIBCXX_ASSERTIONS test net, and frame capture), no new dependency; applied to detz::wa and documented in docs/cpp-safety.md. The sanitizer net prescribed by the research then caught a second UB (a varint shift >= 64 bits) that manual review had missed twice | | [`terminal-screenshot-rendering`](terminal-screenshot-rendering/) | 99 (10 / 89) | 2 | 2026-10-27 | 2026-10-27 | Making detz take a PNG of the current terminal on a headless server for WhatsApp: surveyed freeze, termshot, textimg, libansilove, agg, aha, silicon, tmux capture-pane -e, bitmap fonts (Spleen, Terminus, Unifont, X11 fixed) and how Baileys, whatsmeow and whatsapp-rust set image mimetypes; decided an in-process renderer (tmux escapes, TuiVtScreen, embedded Spleen 8x16, zlib PNG) and image/png without a JPEG encoder; implemented the same session | ## Recent activity log @@ -69,7 +70,7 @@ | 2026-10-25 | `background-work-limits` | Extended with 46 sources (5 Tier 1 / 41 Tier 2) + 2 conclusions (`sub-agent-panels-on-the-multiplexer`, `sub-agent-supervision-and-collection`), from 8 searches and 6 fetches on how parallel agents are shown, scheduled, timed out, monitored and how their results are collected (Claude Code agent teams, Temporal activity timeouts, the claim-check pattern, Celery worker limits, tmux layouts, Kubernetes termination, terminal streaming, parallel-agent dashboards). Implemented the same session in taicpp (feed panes, `src/orch/`, supervision, CAP collection) and verified live. Carried gaps: the Kubernetes pod lifecycle page was opened but its termination and probe sections were not returned, so it is a Tier 2 card and its numbers are unverified; the tmux manual was read to character 100000 of 278260 (options unread); the 60 s and 300 s idle limits are static judgments, not measurements. | | 2026-10-27 | `whatsapp-automation` | New subject: 70 sources (9 Tier 1 / 61 Tier 2) + 3 conclusions, from 12 searches, 9 repositories shallow-cloned and read (whatsmeow, libsignal-protocol-go, wa-go, Baileys, neonize, whatsapp-rust, whatsapp-mcp, yowsup, libsignal-protocol-c), line counts and GitHub API activity measured, and one live check (libcurl got 101 from wss://web.whatsapp.com/ws/chat). Mirror and language copies of one page are logged as one card each, with every URL named in the card. Decisions: no native Python library exists and no browser is needed; native C++ `detz::wa` transpiled from wa-go (MIT) with whatsmeow (MPL-2.0) as referee and GPL-3.0 libsignal avoided; whatsapp-mcp through detz's MCP client as the two-day shortcut. Specified in taicpp/docs/whatsapp.md, nothing built. Carried gaps: an unpaired whatsmeow QR probe was refused by the session permission classifier, so the full handshake is unverified here; XEdDSA implementation, LID addressing, client-version policy and ban behaviour are open deep-research items. | | 2026-10-27 | `terminal-screenshot-rendering` | New subject: 99 sources (10 Tier 1 / 89 Tier 2) + 2 conclusions, from 12 searches, 5 page fetches, the Spleen BDF and LICENSE download, 3 source files read in the cloned Baileys, whatsmeow and whatsapp-rust repositories, the local console-setup font copyright file, and live tmux 3.6 captures. Mirror and version copies of one page are one card each, with the URL count in the card title. Decisions: render in-process (capture-pane -e -p -N, TuiVtScreen, embedded Spleen 8x16 BSD-2, zlib PNG); send as image/png, no JPEG encoder. Implemented in taicpp (src/termshot/, terminal_screenshot tool, tests/termshot_test.cpp, docs/termshot.md) and verified with a real model calling the tool. Carried gaps: glyphs outside Spleen render as '?', wide characters take one column, the native plexer path and a live WhatsApp send of image/png are unverified. | - +| 2026-10-27 | `safe-cpp-practices` | New subject: 45 sources (8 Tier 1 / 37 Tier 2) + 2 conclusions, from 6 extended web searches on safe production C++ (OpenSSF compiler hardening, C++ Core Guidelines bounds/GSL/narrow_cast, std::span no-default-bounds-check, integer-overflow size checks, libFuzzer+ASan/UBSan CI, sanitizer overhead ladder, clang-tidy ratchet, GCC -fhardened). Triggered by incident WA-2026-10-27, the `std::vector larger than max_size()` crash in the WhatsApp wire parser. Decisions: a four-layer playbook (overflow-safe checked-reader parsing with `len <= size - pos`; cheap always-on release hardening; an ASan+UBSan+_GLIBCXX_ASSERTIONS test net via tools/san-whatsapp.sh; frame capture as a regression corpus), no new runtime dependency. Applying the research's own prescription (the sanitizer net) immediately caught a second, independent UB (a varint shift of up to 70 bits) that two manual reviews had missed; fixed and guarded. Documented in docs/cpp-safety.md, docs/whatsapp.md section 13, AGENTS.md. Carried gaps: the exact live frame from the user is still unreproduced (capture hook added); clang-tidy narrowing-conversion ratchet not yet wired; ed25519 ref10 excluded from UBSan for intentional shift idioms. | ## How to use this index - Before starting new research, search this table for an existing subject before opening a new one (see [README.md](README.md#2-directory-layout) §2, "one subject, one home"). diff --git a/research/safe-cpp-practices/aws-detector-intoverflow.md b/research/safe-cpp-practices/aws-detector-intoverflow.md new file mode 100644 index 0000000..d639a78 --- /dev/null +++ b/research/safe-cpp-practices/aws-detector-intoverflow.md @@ -0,0 +1,28 @@ +# Amazon Q integer-overflow detector + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | Amazon Q integer-overflow detector | +| Source URL | https://docs.aws.amazon.com/amazonq/detector-library/c/integer-overflow | +| Source type | vendor docs | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Static detector entry for the bug class. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/bitcoinsv-clangtidy.md b/research/safe-cpp-practices/bitcoinsv-clangtidy.md new file mode 100644 index 0000000..933536d --- /dev/null +++ b/research/safe-cpp-practices/bitcoinsv-clangtidy.md @@ -0,0 +1,28 @@ +# bitcoin-sv/bdk PR#74: clang-tidy in CI + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | bitcoin-sv/bdk PR#74: clang-tidy in CI | +| Source URL | https://github.com/bitcoin-sv/bdk/pull/74 | +| Source type | repository | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Curated check set + parked to-do list, warnings-as-errors. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/cfncloud-stack-protection.md b/research/safe-cpp-practices/cfncloud-stack-protection.md new file mode 100644 index 0000000..dbf07b3 --- /dev/null +++ b/research/safe-cpp-practices/cfncloud-stack-protection.md @@ -0,0 +1,28 @@ +# Linux Stack Overflow Protection: Canaries, NX, ASLR, PIE, RELRO + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | Linux Stack Overflow Protection: Canaries, NX, ASLR, PIE, RELRO | +| Source URL | https://www.cfncloud.com/en/p/linux-stack-overflow-protection | +| Source type | blog post | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Background on the runtime protections the flags enable. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/clang-tidy-fix-bench.md b/research/safe-cpp-practices/clang-tidy-fix-bench.md new file mode 100644 index 0000000..9a8bded --- /dev/null +++ b/research/safe-cpp-practices/clang-tidy-fix-bench.md @@ -0,0 +1,28 @@ +# cpp-linter/clang-tidy-fix-bench + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | cpp-linter/clang-tidy-fix-bench | +| Source URL | https://github.com/cpp-linter/clang-tidy-fix-bench | +| Source type | repository | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Many checks have no auto-fix; manual triage burden. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/clang-tidy-production-ratchet.md b/research/safe-cpp-practices/clang-tidy-production-ratchet.md new file mode 100644 index 0000000..274d1f8 --- /dev/null +++ b/research/safe-cpp-practices/clang-tidy-production-ratchet.md @@ -0,0 +1,50 @@ +# Adopting clang-tidy in CI as a ratchet (bugprone, cppcoreguidelines) + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Dossier | +| Tier | 1 | +| Source title | Adopting clang-tidy in CI as a ratchet (bugprone, cppcoreguidelines) | +| Source URL | https://clang.llvm.org/extra/clang-tidy/ | +| Source publisher / author | LLVM; bitcoin-sv/bdk, ShipSoft, Eigen (CI examples) | +| Source type | repository | +| Source date (published) | Unknown — not stated | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | web search synthesis | +| Confidence | Medium | +| Status | Active | + +## Summary + +Real projects adopt clang-tidy with a curated check set (bugprone, clang-analyzer, cppcoreguidelines, performance), warnings-as-errors, and a parked list of not-yet-passing checks enabled one at a time: a ratchet. Advisory-on-changed-files first keeps velocity. + +## Key findings + +- Curated set: bugprone-*, clang-analyzer-*, selected cppcoreguidelines-*, performance-*, with -warnings-as-errors. +- Keep failing checks in a disabled to-do list and enable them one at a time with their fixes (the ratchet). +- Run advisory on changed files first (allow-failure) so existing workflows are not blocked (the velocity tradeoff). +- Many bug-finding checks have no auto-fix (e.g. bugprone-narrowing-conversions), so budget manual triage. +- cppcoreguidelines checks are the noisiest; adopt selectively. + +## Pros / strengths + +Battle-tested adoption pattern that preserves developer speed; narrowing-conversion check targets the exact bug class. + +## Cons / limitations / caveats + +No official production recommendation; noise and manual-fix burden are real; detz has not wired clang-tidy yet (stated as the next ratchet step). + +## Relevance to tai + +Points to bugprone-narrowing-conversions and the cppcoreguidelines bounds checks as the static-analysis layer that would have flagged the implicit int->size_t narrowing; detz records this as the planned next enforcement layer. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Initial dossier created (web search synthesis). | diff --git a/research/safe-cpp-practices/conan-sanitizers.md b/research/safe-cpp-practices/conan-sanitizers.md new file mode 100644 index 0000000..f1dd791 --- /dev/null +++ b/research/safe-cpp-practices/conan-sanitizers.md @@ -0,0 +1,28 @@ +# How to Use Compiler Sanitizers in Your Conan C/C++ Workflow + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | How to Use Compiler Sanitizers in Your Conan C/C++ Workflow | +| Source URL | https://blog.conan.io/sanitizers/toolchain/tools/conan/2025/11/25/How-to-use-sanitizers-in-your-conan-workflow.html | +| Source type | blog post | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Build-system integration of sanitizers. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/conclusions/detz-safe-cpp-playbook.md b/research/safe-cpp-practices/conclusions/detz-safe-cpp-playbook.md new file mode 100644 index 0000000..0cb9930 --- /dev/null +++ b/research/safe-cpp-practices/conclusions/detz-safe-cpp-playbook.md @@ -0,0 +1,49 @@ +# Conclusion: detz safe-C++ playbook: overflow-safe parsing, cheap release hardening, a sanitizer test net, no new dependency + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Conclusion | +| Tier | N/A | +| Date decided | 2026-10-27 | +| Decided by | retoor, advised by tai (agent, Claude Opus 4.8) | +| Status | Active | +| Confidence | High | + +## Question / problem statement + +How does detz write fast, object-oriented C++ that a hostile or buggy peer can never crash or corrupt, without slowing development to a crawl or adding heavy dependencies? + +## Conclusion + +Four layers, cheapest first. (1) Design: parse untrusted bytes through a checked reader that validates every length against remaining bytes with overflow-safe arithmetic (`len <= size - pos`, never `pos + len <= size`), reads lengths into an unsigned type, rejects negatives, and never lets a wire value drive an allocation or slice before it is bounded; guard every varint shift against >= 64 bits; wrap every top-level read/dispatch loop so no exception escapes. RAII and the rule of zero keep resource bugs from existing. (2) Release hardening (cheap, always on): the overflow-safe checks plus libstdc++ fast assertions and fortification per the OpenSSF guide, so a residual bad index is a defined, located failure not undefined behavior. (3) Test net (free at dev time, run in CI): an ASan+UBSan+_GLIBCXX_ASSERTIONS build of the parsers plus a hostile-input and random-fuzz test, via tools/san-whatsapp.sh. (4) Capture: record the exact bytes of any frame that breaks a parser so an unreproducible wire bug becomes a one-paste deterministic fix. No GSL, no new runtime dependency; std::span-style checked views and OpenSSL/zlib already linked. + +## Supporting sources + +- [openssf-compiler-hardening-guide](../openssf-compiler-hardening-guide.md): the cheap release-hardening flag set (_GLIBCXX_ASSERTIONS, fortification, stack-protector). +- [integer-overflow-size-checks](../integer-overflow-size-checks.md): the `len <= size - pos` guard and validate-before-allocate rule, the root-cause cure. +- [libfuzzer-sanitizer-ci](../libfuzzer-sanitizer-ci.md): the sanitizer+fuzz test net and the regression-corpus/capture pattern. +- [sanitizer-overhead-maturity-ladder](../sanitizer-overhead-maturity-ladder.md): why sanitizers are test-only and hardening is release: the overhead numbers and the ladder. +- [cpp-core-guidelines-bounds-gsl](../cpp-core-guidelines-bounds-gsl.md): span-over-pointer+length and explicit checked narrowing instead of silent int->size_t. +- [std-span-no-default-bounds-check](../std-span-no-default-bounds-check.md): why the reader must validate itself and not trust span/subspan to bounds-check. + +## Alternatives considered and rejected + +Adopt GSL wholesale (span/narrow/not_null): rejected as a new dependency; CLAUDE.md says fewer moving parts, and std::span plus a small checked reader covers the need. Turn on sanitizers in release: rejected, 2-3x cost; they are the test net, not the shipping config. Rewrite the wire layer in a memory-safe language: rejected, the project is C++ and the crypto/wire core is proven; the goal is safe C++, not not-C++. + +## Risks / open questions + +Hardening and sanitizers catch memory and UB bugs, not logic bugs; byte-exact golden vectors and the live handshake cover correctness separately. clang-tidy (the narrowing-conversion static layer) is not wired yet, so an implicit narrowing can still be introduced between sanitizer runs; that is the named next ratchet step. ed25519 ref10 is excluded from UBSan for intentional shift idioms, a small unsanitized island. + +## Action taken + +Applied to detz::wa in this session: overflow-safe checks in WaBinary and WaProto (commit f16c5c6), the varint shift guard (this session, caught by the sanitizer net that this research prescribed), the frame-capture hook, tests/whatsapp_test.cpp test_hostile, and tools/san-whatsapp.sh. Documented in docs/cpp-safety.md and docs/whatsapp.md section 13, with the standing rule added to AGENTS.md. clang-tidy ratchet recorded as the next step, not yet wired. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Initial conclusion recorded. | diff --git a/research/safe-cpp-practices/conclusions/incident-wa-length-error-root-cause.md b/research/safe-cpp-practices/conclusions/incident-wa-length-error-root-cause.md new file mode 100644 index 0000000..02b0cc9 --- /dev/null +++ b/research/safe-cpp-practices/conclusions/incident-wa-length-error-root-cause.md @@ -0,0 +1,46 @@ +# Conclusion: Incident WA-2026-10-27: the length_error crash was a size-arithmetic overflow plus an uncaught exception, and a second UB was found by the fix's own test net + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Conclusion | +| Tier | N/A | +| Date decided | 2026-10-27 | +| Decided by | retoor, advised by tai (agent, Claude Opus 4.8) | +| Status | Active | +| Confidence | High | + +## Question / problem statement + +What was the actual defect behind the `cannot create std::vector larger than max_size()` abort during --whatsapp-link, and did the first fix fully resolve it? + +## Conclusion + +The primary defect was an overflowable bounds check (`pos + len > size` wrapping size_t) that let an attacker-sized length reach vector::assign, combined with a node-dispatch loop that did not catch exceptions, so the throw aborted the process. The first fix (commit f16c5c6) made the checks overflow-safe and wrapped dispatch, which stopped the abort but was declared verified on the strength of a hostile-input test that did not exercise the live decode path, which was overconfident. Standing this research up produced the real net: building the parsers under ASan+UBSan+_GLIBCXX_ASSERTIONS immediately surfaced a second, independent undefined-behavior bug that two manual reviews had missed, a varint decode loop that shifted by up to 70 bits (shift >= 64 is UB) on malformed input. That is now fixed and guarded by both a deterministic test and the sanitizer net. The exact live frame that the user hit remains unreproduced in-session; the capture hook will record it on recurrence. + +## Supporting sources + +- [integer-overflow-size-checks](../integer-overflow-size-checks.md): names the signed/overflow size trap that was the primary defect. +- [libfuzzer-sanitizer-ci](../libfuzzer-sanitizer-ci.md): the sanitizer+fuzz approach that found the second (varint shift) UB. +- [sanitizer-overhead-maturity-ladder](../sanitizer-overhead-maturity-ladder.md): UBSan as the cheap oracle that catches shift-overflow UB. + +## Alternatives considered and rejected + +Keep patching sites as they are reported (whack-a-mole): rejected, it is what produced the overconfident first fix; a tool-enforced net is the only thing that finds what review misses. Disable the dispatch try/catch to crash loudly in production: rejected, release must degrade gracefully; the sanitizer build is where we crash loudly. + +## Risks / open questions + +The original live frame is still not reproduced, so a third, distinct decode bug on a specific valid node shape cannot be ruled out; the capture hook is the mitigation and must actually be exercised on the user's next run. The sanitizer net covers the parsers it is pointed at; a new parser added without wiring it in is unguarded. + +## Action taken + +Varint shift guard added and tested; frame-capture hook added to WaClient and wired from the wizard and the agent tool; the whole parser suite runs clean under tools/san-whatsapp.sh; documented as incident WA-2026-10-27 in docs/whatsapp.md section 13. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Initial conclusion recorded. | diff --git a/research/safe-cpp-practices/cpp-core-guidelines-bounds-gsl.md b/research/safe-cpp-practices/cpp-core-guidelines-bounds-gsl.md new file mode 100644 index 0000000..e2c5eba --- /dev/null +++ b/research/safe-cpp-practices/cpp-core-guidelines-bounds-gsl.md @@ -0,0 +1,50 @@ +# C++ Core Guidelines: bounds safety, GSL, narrow_cast, not_null + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Dossier | +| Tier | 1 | +| Source title | C++ Core Guidelines: bounds safety, GSL, narrow_cast, not_null | +| Source URL | http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines | +| Source publisher / author | Bjarne Stroustrup, Herb Sutter (editors), ISO C++ | +| Source type | standard | +| Source date (published) | Unknown — not stated (living document) | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | web search synthesis | +| Confidence | High | +| Status | Active | + +## Summary + +The reference set of rules for modern C++. The bounds-safety profile treats range errors as a class to eliminate: pass span instead of pointer+length, and make narrowing conversions explicit and checked. + +## Key findings + +- Bounds profile: prefer `span` over raw pointer-plus-length parameters so a length cannot be passed wrong. +- `gsl::narrow(x)` converts and throws `narrowing_error` if the value does not round-trip; `narrow_cast` is an explicit, silent, lossy cast. +- ES.46: a negative double through `narrow` throws, while `narrow_cast` silently wraps, which is exactly the signed->size_t trap behind the WhatsApp crash. +- `gsl::not_null` documents and enforces that null is not a valid value for a pointer. +- The guidelines favor RAII and the rule of zero so resource bugs do not exist to be found. + +## Pros / strengths + +The canonical, broadly agreed rulebook; the span and narrow rules map directly onto wire parsing. + +## Cons / limitations / caveats + +Aspirational and large; full adoption is a multi-year ratchet. GSL is a dependency detz chose not to add (uses std::span/own checked reader instead). + +## Relevance to tai + +Names the exact anti-patterns detz hit (implicit narrowing, pointer+length) and the exact cures (explicit checked narrowing, span-style readers). detz applies the principle without the GSL dependency. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Initial dossier created (web search synthesis). | diff --git a/research/safe-cpp-practices/cppreference-span.md b/research/safe-cpp-practices/cppreference-span.md new file mode 100644 index 0000000..b88b296 --- /dev/null +++ b/research/safe-cpp-practices/cppreference-span.md @@ -0,0 +1,28 @@ +# std::span - cppreference + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | std::span - cppreference | +| Source URL | https://en.cppreference.com/cpp/container/span | +| Source type | vendor docs | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +span reference; subspan/operator[] behavior. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/daphne-sanitizer-ci.md b/research/safe-cpp-practices/daphne-sanitizer-ci.md new file mode 100644 index 0000000..6cfceab --- /dev/null +++ b/research/safe-cpp-practices/daphne-sanitizer-ci.md @@ -0,0 +1,28 @@ +# Daphne PR#44: ASan/TSan/libFuzzer in CI + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | Daphne PR#44: ASan/TSan/libFuzzer in CI | +| Source URL | https://github.com/cychang-ykc/Daphne/pull/44 | +| Source type | repository | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +CI wiring example for sanitizers + fuzzing. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/debuggai-fuzzing-2025.md b/research/safe-cpp-practices/debuggai-fuzzing-2025.md new file mode 100644 index 0000000..b9ab161 --- /dev/null +++ b/research/safe-cpp-practices/debuggai-fuzzing-2025.md @@ -0,0 +1,28 @@ +# Make Fuzzing a First-Class Test in 2025 (libFuzzer, AFL++, sanitizers) + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | Make Fuzzing a First-Class Test in 2025 (libFuzzer, AFL++, sanitizers) | +| Source URL | https://debugg.ai/resources/make-fuzzing-first-class-test-2025-coverage-guided-ci-cd | +| Source type | blog post | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +CI cadence: short fuzz on push, long nightly, regression corpus. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/eigen-clangtidy-advisory.md b/research/safe-cpp-practices/eigen-clangtidy-advisory.md new file mode 100644 index 0000000..6b5c82c --- /dev/null +++ b/research/safe-cpp-practices/eigen-clangtidy-advisory.md @@ -0,0 +1,28 @@ +# Eigen MR#2178: clang-tidy + sanitizers, advisory on changed files + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | Eigen MR#2178: clang-tidy + sanitizers, advisory on changed files | +| Source URL | https://gitlab.com/libeigen/eigen/-/merge_requests/2178/commits | +| Source type | repository | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +The developer-velocity tradeoff: advisory, allow-failure, changed-files only. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/embedonix-span.md b/research/safe-cpp-practices/embedonix-span.md new file mode 100644 index 0000000..8edafbc --- /dev/null +++ b/research/safe-cpp-practices/embedonix-span.md @@ -0,0 +1,28 @@ +# Using std::span in Modern C++ + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | Using std::span in Modern C++ | +| Source URL | https://www.embedonix.com/articles/using-stdspan-in-modern-c-programming/ | +| Source type | blog post | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +span has no runtime bounds check in C++20; validate length before reading payload. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/finos-cg-slides.md b/research/safe-cpp-practices/finos-cg-slides.md new file mode 100644 index 0000000..47fb309 --- /dev/null +++ b/research/safe-cpp-practices/finos-cg-slides.md @@ -0,0 +1,28 @@ +# The C++ Core Guidelines Project (Stroustrup slides) + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | The C++ Core Guidelines Project (Stroustrup slides) | +| Source URL | https://www.finos.org/hubfs/FINOS/OSSF%202019/2019%20Slides/CG%20one%20hour.pdf | +| Source type | other | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Overview deck of the Core Guidelines goals. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/gcc-fhardened.md b/research/safe-cpp-practices/gcc-fhardened.md new file mode 100644 index 0000000..c1935ce --- /dev/null +++ b/research/safe-cpp-practices/gcc-fhardened.md @@ -0,0 +1,49 @@ +# GCC -fhardened and Clang -fhardened: a production hardening bundle + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Dossier | +| Tier | 1 | +| Source title | GCC -fhardened and Clang -fhardened: a production hardening bundle | +| Source URL | https://github.com/llvm/llvm-project/issues/122687 | +| Source publisher / author | GCC; LLVM project (issue 122687) | +| Source type | repository | +| Source date (published) | Unknown — not stated | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | web search synthesis | +| Confidence | Medium | +| Status | Active | + +## Summary + +GCC's -fhardened is a single flag that turns on a production hardening bundle, and Clang is adding the same. It bundles the OpenSSF-style set so projects do not hand-maintain the list. + +## Key findings + +- GCC -fhardened bundles _FORTIFY_SOURCE=3, _GLIBCXX_ASSERTIONS, -ftrivial-auto-var-init=zero, PIE, RELRO, -fstack-protector-strong, stack-clash protection. +- If glibc is older than 2.35 it falls back to _FORTIFY_SOURCE=2. +- The exact set may change between major GCC releases, so it is a moving (improving) target. +- Commentary: these protections are cheap enough that major Linux distributions already ship them by default. + +## Pros / strengths + +One flag, maintained by the toolchain, tracks evolving best practice. + +## Cons / limitations / caveats + +Set changes across releases (reproducibility caveat); a project's own configure can override pieces; not yet in all shipping Clang versions. + +## Relevance to tai + +A future simplification for detz's release build (replace the hand-listed hardening flags with -fhardened once the toolchain baseline supports it). + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Initial dossier created (web search synthesis). | diff --git a/research/safe-cpp-practices/github-gsl-lite.md b/research/safe-cpp-practices/github-gsl-lite.md new file mode 100644 index 0000000..fd2dd63 --- /dev/null +++ b/research/safe-cpp-practices/github-gsl-lite.md @@ -0,0 +1,28 @@ +# gsl-lite/gsl-lite + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | gsl-lite/gsl-lite | +| Source URL | https://github.com/gsl-lite/gsl-lite | +| Source type | repository | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Pre-C++20 GSL implementation; not_null move-state difference from Microsoft GSL. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/github-imshark-fuzz.md b/research/safe-cpp-practices/github-imshark-fuzz.md new file mode 100644 index 0000000..b5bf131 --- /dev/null +++ b/research/safe-cpp-practices/github-imshark-fuzz.md @@ -0,0 +1,28 @@ +# imshark PR#13: add libFuzzer harnesses and fix parser bugs + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | imshark PR#13: add libFuzzer harnesses and fix parser bugs | +| Source URL | https://github.com/Zaryob/imshark/pull/13 | +| Source type | repository | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Worked example of adding fuzzing and fixing the bugs it found in a parser. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/github-microsoft-gsl.md b/research/safe-cpp-practices/github-microsoft-gsl.md new file mode 100644 index 0000000..ccb8927 --- /dev/null +++ b/research/safe-cpp-practices/github-microsoft-gsl.md @@ -0,0 +1,28 @@ +# microsoft/GSL + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | microsoft/GSL | +| Source URL | https://github.com/microsoft/GSL | +| Source type | repository | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Reference GSL implementation. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/guzenfeld-lowlatency.md b/research/safe-cpp-practices/guzenfeld-lowlatency.md new file mode 100644 index 0000000..6fb2ee9 --- /dev/null +++ b/research/safe-cpp-practices/guzenfeld-lowlatency.md @@ -0,0 +1,28 @@ +# C++ Low-Latency, Enforced: builtins, flags, clang-tidy, benchmarked + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | C++ Low-Latency, Enforced: builtins, flags, clang-tidy, benchmarked | +| Source URL | https://pavelguzenfeld.com/posts/cpp-builtins-compiler-flags-clang-tidy/ | +| Source type | blog post | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Combining flags and clang-tidy under a latency budget. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/hn-hardening-overhead.md b/research/safe-cpp-practices/hn-hardening-overhead.md new file mode 100644 index 0000000..4c1fd5e --- /dev/null +++ b/research/safe-cpp-practices/hn-hardening-overhead.md @@ -0,0 +1,28 @@ +# HN: performance overhead of hardening flags + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | HN: performance overhead of hardening flags | +| Source URL | https://news.ycombinator.com/item?id=18874113 | +| Source type | forum thread | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Discussion that distros ship these by default. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/integer-overflow-size-checks.md b/research/safe-cpp-practices/integer-overflow-size-checks.md new file mode 100644 index 0000000..ad98a48 --- /dev/null +++ b/research/safe-cpp-practices/integer-overflow-size-checks.md @@ -0,0 +1,50 @@ +# Integer overflow and allocation-size checks in C/C++ + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Dossier | +| Tier | 1 | +| Source title | Integer overflow and allocation-size checks in C/C++ | +| Source URL | https://offlinemark.com/int-overflow/ | +| Source publisher / author | offlinemark; Offensive360; Orbis AppSec | +| Source type | blog post | +| Source date (published) | Unknown — not stated | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | web search synthesis | +| Confidence | High | +| Status | Active | + +## Summary + +The canonical guidance for size arithmetic on untrusted input: check before the operation, never after, and never let a parsed count drive allocation or pointer math before its range and an application limit are both checked. + +## Key findings + +- Addition overflow guard for size_t: test `a > SIZE_MAX - b` before computing `a + b` (exactly the `len > size - pos` form detz now uses). +- Multiplication guard: `b != 0 && a > SIZE_MAX / b`. +- Checking a signed result after the fact is too late: the overflow was already undefined behavior. +- A negative value converted to an unsigned size becomes huge; validate parsed numbers before the conversion. +- Keep the validated count next to the allocation so the allocation and the loop cannot use different counts. + +## Pros / strengths + +Precise, copy-pasteable guards; names the signed->unsigned trap that caused the crash. + +## Cons / limitations / caveats + +Blog-level sourcing, not a standard; no single authoritative citation. + +## Relevance to tai + +This is the root-cause cure. detz replaced every `pos + len > size` with `len > size - pos`, reads lengths unsigned, and range-checks before slicing or allocating. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Initial dossier created (web search synthesis). | diff --git a/research/safe-cpp-practices/libfuzzer-sanitizer-ci.md b/research/safe-cpp-practices/libfuzzer-sanitizer-ci.md new file mode 100644 index 0000000..1f8b463 --- /dev/null +++ b/research/safe-cpp-practices/libfuzzer-sanitizer-ci.md @@ -0,0 +1,50 @@ +# Coverage-guided fuzzing of parsers with libFuzzer + ASan/UBSan in CI + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Dossier | +| Tier | 1 | +| Source title | Coverage-guided fuzzing of parsers with libFuzzer + ASan/UBSan in CI | +| Source URL | https://appsec.guide/docs/fuzzing/c-cpp/libfuzzer/ | +| Source publisher / author | Trail of Bits (appsec.guide); debugg.ai | +| Source type | vendor docs | +| Source date (published) | Unknown — not stated | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | web search synthesis | +| Confidence | High | +| Status | Active | + +## Summary + +The standard way to harden an untrusted binary parser: a fuzz harness per entry point, built with -fsanitize=fuzzer,address,undefined and -fno-sanitize-recover, run short on every push and long nightly, with a regression corpus of past crashes rerun on every build. + +## Key findings + +- Build with `-fsanitize=fuzzer,address,undefined` and `-fno-sanitize-recover` so a finding aborts rather than warns. +- One harness per untrusted-input entry point, with bounded input sizes. +- Keep a regression corpus of past crashing inputs and rerun it on every build. +- 'No crashes' only means something if the harness reaches the risky code, so track coverage. +- ASan adds ~2-4x runtime; it is a test tool, not a release one. + +## Pros / strengths + +Concrete, matches industry practice; the regression-corpus rule is exactly what turns an unreproducible bug into a permanent test. + +## Cons / limitations / caveats + +libFuzzer is now maintenance-only at LLVM (successor: Centipede); the CI pattern is unaffected but tool choice may shift. + +## Relevance to tai + +detz adopts the pattern at its scale: a deterministic hostile-input test plus a random-input fuzz in whatsapp_test, run under ASan+UBSan via tools/san-whatsapp.sh, and a captured-frame file as the regression corpus seed. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Initial dossier created (web search synthesis). | diff --git a/research/safe-cpp-practices/meetingcpp-sanitizers-2025.md b/research/safe-cpp-practices/meetingcpp-sanitizers-2025.md new file mode 100644 index 0000000..86ad49e --- /dev/null +++ b/research/safe-cpp-practices/meetingcpp-sanitizers-2025.md @@ -0,0 +1,28 @@ +# Meeting C++ 2025: Sanitizers talk (Bloomberg) + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | Meeting C++ 2025: Sanitizers talk (Bloomberg) | +| Source URL | https://meetingcpp.com/mcpp/slides/2025/meetingcpp-talk-2025-sanitizers952457.pdf | +| Source type | other | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Sanitizer overhead figures and usage guidance. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/microsoft-gsl-3-0.md b/research/safe-cpp-practices/microsoft-gsl-3-0.md new file mode 100644 index 0000000..87556f0 --- /dev/null +++ b/research/safe-cpp-practices/microsoft-gsl-3-0.md @@ -0,0 +1,28 @@ +# GSL 3.0.0 Release - C++ Team Blog + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | GSL 3.0.0 Release - C++ Team Blog | +| Source URL | https://devblogs.microsoft.com/cppblog/gsl-3-0-0-release/ | +| Source type | vendor docs | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +GSL span bounds checking and the signed->unsigned ptrdiff/size_t migration caveat. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/modernescpp-bounds.md b/research/safe-cpp-practices/modernescpp-bounds.md new file mode 100644 index 0000000..826a5ec --- /dev/null +++ b/research/safe-cpp-practices/modernescpp-bounds.md @@ -0,0 +1,28 @@ +# C++ Core Guidelines: Bounds Safety + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | C++ Core Guidelines: Bounds Safety | +| Source URL | https://www.modernescpp.com/index.php/c-core-guidelines-bounds-safety/ | +| Source type | blog post | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Bounds profile overview (claims span checks bounds, the weaker reading). + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/modernescpp-gsl.md b/research/safe-cpp-practices/modernescpp-gsl.md new file mode 100644 index 0000000..a9c0890 --- /dev/null +++ b/research/safe-cpp-practices/modernescpp-gsl.md @@ -0,0 +1,28 @@ +# C++ Core Guideline: The Guidelines Support Library + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | C++ Core Guideline: The Guidelines Support Library | +| Source URL | https://www.modernescpp.com/index.php/c-core-guideline-the-guidelines-support-library/ | +| Source type | blog post | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +GSL overview; span/narrow/not_null from the Core Guidelines search. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/ms-ntintsafe.md b/research/safe-cpp-practices/ms-ntintsafe.md new file mode 100644 index 0000000..c24196e --- /dev/null +++ b/research/safe-cpp-practices/ms-ntintsafe.md @@ -0,0 +1,28 @@ +# ntintsafe design guide (Windows) + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | ntintsafe design guide (Windows) | +| Source URL | https://learn.microsoft.com/uk-ua/windows-hardware/drivers/kernel/ntintsafe-design-guide | +| Source type | vendor docs | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Microsoft's safe-integer arithmetic helpers. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/msvc-c26472.md b/research/safe-cpp-practices/msvc-c26472.md new file mode 100644 index 0000000..1a7d2e2 --- /dev/null +++ b/research/safe-cpp-practices/msvc-c26472.md @@ -0,0 +1,28 @@ +# Warning C26472 (use gsl::narrow_cast) + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | Warning C26472 (use gsl::narrow_cast) | +| Source URL | https://learn.microsoft.com/en-us/cpp/code-quality/c26472?view=msvc-170 | +| Source type | vendor docs | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +MSVC analyzer flags arithmetic static_cast, suggests narrow/narrow_cast. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/nhimg-fuzzing-guide.md b/research/safe-cpp-practices/nhimg-fuzzing-guide.md new file mode 100644 index 0000000..0c41710 --- /dev/null +++ b/research/safe-cpp-practices/nhimg-fuzzing-guide.md @@ -0,0 +1,28 @@ +# Fuzzing Guide: Coverage-Guided, API and Protocol Fuzzing + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | Fuzzing Guide: Coverage-Guided, API and Protocol Fuzzing | +| Source URL | https://nhimg.org/fuzzing-guide | +| Source type | other | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Protocol fuzzing seeds and dictionaries. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/nhimg-secure-coding.md b/research/safe-cpp-practices/nhimg-secure-coding.md new file mode 100644 index 0000000..f18a173 --- /dev/null +++ b/research/safe-cpp-practices/nhimg-secure-coding.md @@ -0,0 +1,28 @@ +# C and C++ Secure Coding: Memory Safety and Hardening + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | C and C++ Secure Coding: Memory Safety and Hardening | +| Source URL | https://nhimg.org/c-and-c-plus-plus-secure-coding-guide | +| Source type | other | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Secure-coding overview from the hardening search. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/offensive360-intoverflow.md b/research/safe-cpp-practices/offensive360-intoverflow.md new file mode 100644 index 0000000..9b7ee76 --- /dev/null +++ b/research/safe-cpp-practices/offensive360-intoverflow.md @@ -0,0 +1,28 @@ +# Integer Overflow and Allocation Size Checks + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | Integer Overflow and Allocation Size Checks | +| Source URL | https://knowledge-base.offensive360.com/IntegerOverflow/ | +| Source type | other | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +The validate-before-allocate and keep-count-with-allocation rules. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/office-cpp-guidelines.md b/research/safe-cpp-practices/office-cpp-guidelines.md new file mode 100644 index 0000000..bbff503 --- /dev/null +++ b/research/safe-cpp-practices/office-cpp-guidelines.md @@ -0,0 +1,28 @@ +# C++ Core Guidelines (Office fork) + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | C++ Core Guidelines (Office fork) | +| Source URL | https://microsoft.github.io/OfficeCppGuidelines/CppCoreGuidelines.html | +| Source type | vendor docs | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +A team fork of the guidelines. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/openssf-compiler-hardening-guide.md b/research/safe-cpp-practices/openssf-compiler-hardening-guide.md new file mode 100644 index 0000000..0668b36 --- /dev/null +++ b/research/safe-cpp-practices/openssf-compiler-hardening-guide.md @@ -0,0 +1,51 @@ +# OpenSSF Compiler Options Hardening Guide for C and C++ + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Dossier | +| Tier | 1 | +| Source title | OpenSSF Compiler Options Hardening Guide for C and C++ | +| Source URL | https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html | +| Source publisher / author | Open Source Security Foundation (OpenSSF) Best Practices WG | +| Source type | standard | +| Source date (published) | Unknown — not stated (living document) | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | web search synthesis | +| Confidence | High | +| Status | Active | + +## Summary + +The authoritative, vendor-neutral list of compiler and linker flags that harden a C/C++ binary in production. It pairs library precondition checks with stack and fortification protections and states the cost of each. + +## Key findings + +- Recommended production set pairs `_GLIBCXX_ASSERTIONS` with `_FORTIFY_SOURCE=3`, `-fstack-protector-strong`, and `-fstack-clash-protection`. +- `_GLIBCXX_ASSERTIONS` turns libstdc++ preconditions (container bounds, valid iterators) into checks; it has a small, roughly constant-time cost suitable for release. +- The full set also includes RELRO, noexecstack, PIE, and `-fstrict-flex-arrays=3`. +- The standard library's 'fast' hardening mode is security-critical constant-time checks meant to stay on in production; heavier fortification can cost performance. +- `-fstack-protector-strong` is called out as the balance point between coverage and cost. +- `_FORTIFY_SOURCE` is not general memory safety, and sanitizers can misbehave when combined with source fortification. + +## Pros / strengths + +Authoritative, concrete flag lists, honest about cost, separates cheap-always-on from expensive-test-only. + +## Cons / limitations / caveats + +A menu, not a policy: a project still must decide which flags gate release vs test. Says little about C++-level API design. + +## Relevance to tai + +Directly answers 'how do we make release builds catch the length_error/over-index class cheaply': _GLIBCXX_ASSERTIONS plus fortification. detz adopts the cheap subset for release and the full sanitizer set for the test net. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Initial dossier created (web search synthesis). | diff --git a/research/safe-cpp-practices/orbis-image-overflow.md b/research/safe-cpp-practices/orbis-image-overflow.md new file mode 100644 index 0000000..322fb3a --- /dev/null +++ b/research/safe-cpp-practices/orbis-image-overflow.md @@ -0,0 +1,28 @@ +# How Integer Overflow happens in C++ image processing and how to fix it + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | How Integer Overflow happens in C++ image processing and how to fix it | +| Source URL | https://orbisappsec.com/blog/how-integer-overflow-happens-in-c-image-processing-and-how-to-fix | +| Source type | blog post | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Real signed-int-product-into-size_t allocation bug and its fix. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/ossf-hardening-md.md b/research/safe-cpp-practices/ossf-hardening-md.md new file mode 100644 index 0000000..93c20d2 --- /dev/null +++ b/research/safe-cpp-practices/ossf-hardening-md.md @@ -0,0 +1,28 @@ +# OpenSSF Compiler-Hardening-Guide (GitHub source) + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | OpenSSF Compiler-Hardening-Guide (GitHub source) | +| Source URL | https://github.com/ossf/wg-best-practices-os-developers/blob/main/docs/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.md | +| Source type | repository | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Source markdown of the OpenSSF hardening guide. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/pardisp-clang-sanitizers.md b/research/safe-cpp-practices/pardisp-clang-sanitizers.md new file mode 100644 index 0000000..648b552 --- /dev/null +++ b/research/safe-cpp-practices/pardisp-clang-sanitizers.md @@ -0,0 +1,28 @@ +# Hardening C/C++ Code with Clang Sanitizers + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | Hardening C/C++ Code with Clang Sanitizers | +| Source URL | https://pardisp.github.io/blog/post_2.html | +| Source type | blog post | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Overview of the Clang sanitizer family. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/platformio-clangtidy.md b/research/safe-cpp-practices/platformio-clangtidy.md new file mode 100644 index 0000000..cf6d210 --- /dev/null +++ b/research/safe-cpp-practices/platformio-clangtidy.md @@ -0,0 +1,28 @@ +# Clang-Tidy (PlatformIO docs) + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | Clang-Tidy (PlatformIO docs) | +| Source URL | https://docs.platformio.org/en/latest/advanced/static-code-analysis/tools/clang-tidy.html | +| Source type | vendor docs | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Check prefixes and usage. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/redhat-gcc-flags.md b/research/safe-cpp-practices/redhat-gcc-flags.md new file mode 100644 index 0000000..d3cd448 --- /dev/null +++ b/research/safe-cpp-practices/redhat-gcc-flags.md @@ -0,0 +1,28 @@ +# Recommended compiler and linker flags for GCC (Red Hat) + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | Recommended compiler and linker flags for GCC (Red Hat) | +| Source URL | https://developers.redhat.com/blog/2018/03/21/compiler-and-linker-flags-gcc | +| Source type | blog post | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Older but widely cited GCC hardening flag recommendations. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/sanitizer-overhead-maturity-ladder.md b/research/safe-cpp-practices/sanitizer-overhead-maturity-ladder.md new file mode 100644 index 0000000..72d49d2 --- /dev/null +++ b/research/safe-cpp-practices/sanitizer-overhead-maturity-ladder.md @@ -0,0 +1,50 @@ +# Sanitizer overhead and the debug/test/release maturity ladder + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Dossier | +| Tier | 1 | +| Source title | Sanitizer overhead and the debug/test/release maturity ladder | +| Source URL | https://microblink.com/be-wise-sanitize-keeping-your-c-code-free-from-bugs/ | +| Source publisher / author | Microblink; Meeting C++ 2025 (Bloomberg); Sanitizers Handbook | +| Source type | blog post | +| Source date (published) | Unknown — not stated | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | web search synthesis | +| Confidence | Medium | +| Status | Active | + +## Summary + +Sanitizers are a debug/test/fuzz tool, not a release one, because of their cost; cheap hardening flags stay on in release. Measured overheads: ASan ~2-3x, TSan ~5-15x, UBSan ~1.25x. + +## Key findings + +- ASan roughly 2-3x slowdown; TSan 5-15x; UBSan about 1.25x CPU and no memory overhead. +- Sanitizers are too expensive for release; they belong in debug, test and fuzz builds. +- Cheap hardening (fast hardening mode, stack-protector-strong) stays on in release. +- A maturity ladder: local developer runs -> sanitizer CI -> nightly sanitizer suites -> fuzzing sanitizer jobs. +- RAII and the rule of zero cost nothing at runtime and shrink the bug surface sanitizers must cover. + +## Pros / strengths + +Gives the numbers needed to decide what gates release vs test; the ladder is a clear adoption plan. + +## Cons / limitations / caveats + +Overhead figures vary by workload; blog/conference sourcing, not measured on detz. + +## Relevance to tai + +Justifies detz's split: release gets the overflow-safe checks plus cheap libstdc++ assertions; the sanitizer net (ASan+UBSan) runs in the test suite, where it already caught a real UB varint bug. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Initial dossier created (web search synthesis). | diff --git a/research/safe-cpp-practices/sanitizers-handbook.md b/research/safe-cpp-practices/sanitizers-handbook.md new file mode 100644 index 0000000..9e4555a --- /dev/null +++ b/research/safe-cpp-practices/sanitizers-handbook.md @@ -0,0 +1,28 @@ +# The Complete C/C++ Sanitizers Handbook (gist) + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | The Complete C/C++ Sanitizers Handbook (gist) | +| Source URL | https://gist.github.com/MangaD/3b46e4c5ef4c63e44a21bed39ae64093 | +| Source type | other | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Per-sanitizer overhead and combination rules (ASan+UBSan, not with MSan). + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/shipsoft-clangtidy-ratchet.md b/research/safe-cpp-practices/shipsoft-clangtidy-ratchet.md new file mode 100644 index 0000000..0497bf2 --- /dev/null +++ b/research/safe-cpp-practices/shipsoft-clangtidy-ratchet.md @@ -0,0 +1,28 @@ +# ShipSoft PR#23: enforce Core Guidelines with a clang-tidy ratchet + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | ShipSoft PR#23: enforce Core Guidelines with a clang-tidy ratchet | +| Source URL | https://github.com/ShipSoft/.github/pull/23 | +| Source type | repository | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Ratchet argument for pushing toward modern C++. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/sqlpey-intoverflow.md b/research/safe-cpp-practices/sqlpey-intoverflow.md new file mode 100644 index 0000000..fce9acb --- /dev/null +++ b/research/safe-cpp-practices/sqlpey-intoverflow.md @@ -0,0 +1,28 @@ +# C/C++ Integer Overflow: Detection and Prevention Strategies + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | C/C++ Integer Overflow: Detection and Prevention Strategies | +| Source URL | https://sqlpey.com/c++/integer-overflow-detection-prevention/ | +| Source type | blog post | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Overflow detection techniques. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/std-span-no-default-bounds-check.md b/research/safe-cpp-practices/std-span-no-default-bounds-check.md new file mode 100644 index 0000000..e9cd8e0 --- /dev/null +++ b/research/safe-cpp-practices/std-span-no-default-bounds-check.md @@ -0,0 +1,49 @@ +# std::span / subspan: no default bounds checking (cppreference, Embedonix, ModernesCpp) + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Dossier | +| Tier | 1 | +| Source title | std::span / subspan: no default bounds checking (cppreference, Embedonix, ModernesCpp) | +| Source URL | https://en.cppreference.com/cpp/container/span | +| Source publisher / author | cppreference.com; Embedonix; ModernesCpp | +| Source type | vendor docs | +| Source date (published) | Unknown — not stated | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | web search synthesis | +| Confidence | Medium | +| Status | Active | + +## Summary + +std::span is the right type for a non-owning view of bytes, but its operator[] and subspan do not range-check by default; the parser must validate before it slices. + +## Key findings + +- `subspan` with an offset past the end is undefined behavior; it does not throw. +- `span::operator[]` has no runtime check in C++20; `at()` only arrives in C++26. +- For packet parsing, confirm the frame holds header plus the claimed payload length before reading the payload. +- GSL and tcb::span check preconditions only when NDEBUG is not defined, so bounds checking is an implementation choice, not a standard guarantee. + +## Pros / strengths + +Clear, correct caveat that prevents a false sense of safety from using span. + +## Cons / limitations / caveats + +Synthesized from several secondary pages; the ModernesCpp claim that span checks bounds conflicts with the others and is the weaker reading. + +## Relevance to tai + +detz's decoder is a checked reader over a byte view: it validates length against remaining bytes before every slice, never relying on span/subspan to catch a bad offset. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Initial dossier created (web search synthesis). | diff --git a/research/safe-cpp-practices/tcbrindle-span.md b/research/safe-cpp-practices/tcbrindle-span.md new file mode 100644 index 0000000..9c24ff6 --- /dev/null +++ b/research/safe-cpp-practices/tcbrindle-span.md @@ -0,0 +1,28 @@ +# tcbrindle/span (C++20 span backport) + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | tcbrindle/span (C++20 span backport) | +| Source URL | https://github.com/tcbrindle/span | +| Source type | repository | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Backport; checks preconditions only when NDEBUG undefined. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/trailofbits-libfuzzer-skill.md b/research/safe-cpp-practices/trailofbits-libfuzzer-skill.md new file mode 100644 index 0000000..59b2871 --- /dev/null +++ b/research/safe-cpp-practices/trailofbits-libfuzzer-skill.md @@ -0,0 +1,28 @@ +# Trail of Bits libFuzzer testing-handbook skill + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | Trail of Bits libFuzzer testing-handbook skill | +| Source URL | https://github.com/trailofbits/skills/blob/main/plugins/testing-handbook-skills/skills/libfuzzer/SKILL.md | +| Source type | repository | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +libFuzzer flags and harness guidance. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/research/safe-cpp-practices/yunolay-fuzzing.md b/research/safe-cpp-practices/yunolay-fuzzing.md new file mode 100644 index 0000000..fc94aa4 --- /dev/null +++ b/research/safe-cpp-practices/yunolay-fuzzing.md @@ -0,0 +1,28 @@ +# Fuzzing Fundamentals with AFL++ and libFuzzer + +## Metadata + +| Field | Value | +|---|---| +| Institute | Molodetz Institute — Research & Retrieval Division | +| Subject | safe-cpp-practices | +| Document type | Source Citation Card | +| Tier | 2 | +| Source title | Fuzzing Fundamentals with AFL++ and libFuzzer | +| Source URL | https://yunolay.com/fuzzing-fundamentals-with-afl-and-libfuzzer/ | +| Source type | blog post | +| Date researched | 2026-10-27 | +| Researched by | tai (agent), model: Claude Opus 4.8, on behalf of retoor | +| Research method | Search aggregator result listing (not independently opened or quoted) | +| Confidence | Not independently verified | +| Status | Active | + +## Why it's here + +Intro to the two main C/C++ fuzzers. + +## Changelog + +| Date | Change | +|---|---| +| 2026-10-27 | Logged as consulted-but-not-analyzed. | diff --git a/taicpp/docs/cap.md b/taicpp/docs/cap.md index 8b52413..7edc51b 100644 --- a/taicpp/docs/cap.md +++ b/taicpp/docs/cap.md @@ -5,6 +5,8 @@ normative text in `../cap.md`. Namespace `detz::cap`, sources in `src/cap/`, one class per `.h`/`.cpp` pair. The C++ names are the Python names in camelCase; behavior is verified by running both programs (see Verification). +**Wire parsing is untrusted input**: every byte here comes off a socket, so the parsers follow [cpp-safety.md](cpp-safety.md) (overflow-safe size checks, unsigned range-checked lengths, guarded shifts, no exception escaping the read loop, hostile-input tests under sanitizers). We do not accept regressions in that. + ## Spec delta (this milestone) - Real `TAI_CAP_MANIFEST` replaces the one-line placeholder diff --git a/taicpp/docs/mcp.md b/taicpp/docs/mcp.md index 8bf4833..bc6a026 100644 --- a/taicpp/docs/mcp.md +++ b/taicpp/docs/mcp.md @@ -4,6 +4,8 @@ Port of the MCP section of `../tai.py`, normative text in `../mcp.md`. Namespace `detz::mcp`, sources in `src/mcp/`. Reuses the `detz::wire` layer from `src/cap/` (see `docs/cap.md`). +**Wire parsing is untrusted input**: every byte here comes off a socket, so the parsers follow [cpp-safety.md](cpp-safety.md) (overflow-safe size checks, unsigned range-checked lengths, guarded shifts, no exception escaping the read loop, hostile-input tests under sanitizers). We do not accept regressions in that. + ## Spec delta (this milestone) The placeholder `serve_list`/`serve_call` is replaced by the real client, diff --git a/taicpp/docs/whatsapp.md b/taicpp/docs/whatsapp.md index 37dd69f..9ac26ce 100644 --- a/taicpp/docs/whatsapp.md +++ b/taicpp/docs/whatsapp.md @@ -493,3 +493,33 @@ Each case `catch`es `std::length_error` and fails the test if it is thrown, so if anyone reintroduces a `pos + len` check or an unguarded slice, this test goes red. If you add a new parser, add its hostile cases here in the same pass; a parser with no adversarial test is treated as unfinished. + +### 13.6 Follow-up: the first fix was not enough, and how we proved it + +Section 13.3's fix stopped the abort but was declared "verified" on a +hostile-input test that never exercised the live decode path. That was +overconfident: a later run still logged `dropped node : cannot create +std::vector larger than max_size()`. The crash was gone (the `try/catch` held), +but a real frame was still being mis-handled and dropped. + +The cure was to stop reasoning and use a tool. Building the parsers under +AddressSanitizer + UndefinedBehaviorSanitizer + `_GLIBCXX_ASSERTIONS` +([`../tools/san-whatsapp.sh`](../tools/san-whatsapp.sh)) immediately found a +second, independent undefined-behavior bug that two manual reviews had missed: +a protobuf varint loop that shifted by up to 70 bits (shift >= 64 is UB) on +malformed input. It is now fixed and guarded by a deterministic test case and +the sanitizer net. Two more defenses were added: + +- **Frame capture.** `WaClient` records the exact bytes of any frame that fails + to decode or dispatch to `/whatsapp/last-error.log` (bounded). The next + time the still-unreproduced live `` failure happens, the precise input is + on disk and becomes a one-paste regression test and a deterministic fix. +- **The sanitizer net is now the standing requirement**, not a one-off. See the + project-wide playbook, [cpp-safety.md](cpp-safety.md), which this incident + produced: overflow-safe checked-reader parsing, cheap always-on release + hardening, the ASan+UBSan test net, and capture. + +The honest open item: the exact frame the user hit is still unreproduced +in-session (the server did not resend it within a 160 s sanitizer run). The +capture hook exists precisely so that gap closes on its next occurrence rather +than by more guessing. diff --git a/taicpp/src/agent/tools_ops.cpp b/taicpp/src/agent/tools_ops.cpp index e70756e..f6e7d72 100644 --- a/taicpp/src/agent/tools_ops.cpp +++ b/taicpp/src/agent/tools_ops.cpp @@ -758,6 +758,7 @@ std::string Tools::run_whatsapp_send(const json::Value& args) { } wa::WaClient client(store); + client.set_capture_path(app.config.home + "/whatsapp/last-error.log"); std::string log_tail; client.on_log = [&](const std::string& s) { log_tail += "\n " + s; }; if (!client.connect()) return "error: could not connect to WhatsApp (check network)" + log_tail; diff --git a/taicpp/src/whatsapp/wa_client.cpp b/taicpp/src/whatsapp/wa_client.cpp index 925be8a..b09b73e 100644 --- a/taicpp/src/whatsapp/wa_client.cpp +++ b/taicpp/src/whatsapp/wa_client.cpp @@ -4,6 +4,7 @@ #include #include +#include #include "seal_base64.h" #include "wa_binary.h" @@ -100,14 +101,29 @@ std::optional WaClient::recv_node(int timeout_seconds) { log("transport decrypt failed"); return std::nullopt; } + last_plaintext_ = *pt; // kept so a decode/dispatch failure can record the bytes try { return WaBinary::decode(WaBinary::unpack(*pt)); } catch (const std::exception& e) { log(std::string("node decode failed: ") + e.what()); + capture(std::string("decode: ") + e.what()); return std::nullopt; } } +void WaClient::capture(const std::string& reason) { + if (capture_path_.empty() || last_plaintext_.empty()) return; + // bounded: never let the capture file grow without limit. + std::error_code ec; + if (std::filesystem::file_size(capture_path_, ec) > (1u << 20)) std::filesystem::remove(capture_path_, ec); + FILE* f = std::fopen(capture_path_.c_str(), "a"); + if (f == nullptr) return; + std::fprintf(f, "# %s (%zu bytes)\n", reason.c_str(), last_plaintext_.size()); + for (size_t i = 0; i < last_plaintext_.size() && i < 65536; ++i) std::fprintf(f, "%02x", last_plaintext_[i]); + std::fprintf(f, "\n"); + std::fclose(f); +} + void WaClient::send_ack(const WaNode& node) { WaNode ack("ack"); ack.attrs["class"] = node.tag; @@ -124,6 +140,7 @@ void WaClient::dispatch(const WaNode& node) { dispatch_inner(node); } catch (const std::exception& e) { log(std::string("dropped node <") + node.tag + ">: " + e.what()); + capture(std::string("dispatch <") + node.tag + ">: " + e.what()); } } diff --git a/taicpp/src/whatsapp/wa_client.h b/taicpp/src/whatsapp/wa_client.h index b338283..56f2ec3 100644 --- a/taicpp/src/whatsapp/wa_client.h +++ b/taicpp/src/whatsapp/wa_client.h @@ -68,6 +68,12 @@ class WaClient { // Build the QR string for a pair-device ref (whatsmeow makeQRData format). std::string make_qr(const Bytes& ref) const; + // When set, a frame that fails to decode or dispatch has its exact bytes + // appended here (bounded) so an otherwise unreproducible wire bug becomes a + // deterministic, one-paste fix. See docs/whatsapp.md section 13 and + // docs/cpp-safety.md. + void set_capture_path(std::string path) { capture_path_ = std::move(path); } + private: WaStorePort& store_; WaDevice device_; @@ -76,8 +82,11 @@ class WaClient { bool logged_in_{false}; bool paired_event_{false}; uint64_t iq_counter_{0}; + Bytes last_plaintext_; // the most recent decrypted frame, for capture + std::string capture_path_; // where to record a frame that broke a parser void log(const std::string& s); + void capture(const std::string& reason); // record last_plaintext_ (bounded) bool do_handshake(); // send a binary node (framed + noise transport encrypted) void send_node(const WaNode& node); diff --git a/taicpp/src/whatsapp/wa_proto.cpp b/taicpp/src/whatsapp/wa_proto.cpp index ee1c86b..795c5ab 100644 --- a/taicpp/src/whatsapp/wa_proto.cpp +++ b/taicpp/src/whatsapp/wa_proto.cpp @@ -59,6 +59,7 @@ bool ProtoReader::next(Field& out) { v |= static_cast(b & 0x7f) << s; if (!(b & 0x80)) break; s += 7; + if (s > 63) throw std::runtime_error("wa proto: varint too long"); } out.varint = v; return true; diff --git a/taicpp/src/whatsapp/wa_wizard.cpp b/taicpp/src/whatsapp/wa_wizard.cpp index 4baccf6..eb8ab56 100644 --- a/taicpp/src/whatsapp/wa_wizard.cpp +++ b/taicpp/src/whatsapp/wa_wizard.cpp @@ -26,6 +26,7 @@ int WaWizard::link(const std::string& home, const std::string& profile, std::ost } WaClient client(store); + client.set_capture_path(home + "/whatsapp/last-error.log"); bool linked = false; std::string linked_jid; client.on_log = [&](const std::string& s) { out << " " << s << "\n"; }; diff --git a/taicpp/tests/whatsapp_test.cpp b/taicpp/tests/whatsapp_test.cpp index 2086196..5f6f885 100644 --- a/taicpp/tests/whatsapp_test.cpp +++ b/taicpp/tests/whatsapp_test.cpp @@ -284,6 +284,22 @@ static void test_hostile() { } check(ok, "proto reader rejects an oversized length without length_error"); + // 2b. an overlong varint (continuation bytes past 64 bits) must throw, not + // shift-overflow. This is undefined behavior the sanitizer net caught. + Bytes overlong = {0x08}; // field 1, wire 0 + for (int i = 0; i < 12; ++i) overlong.push_back(0x80); // 12 continuation bytes + overlong.push_back(0x01); + ok = true; + try { + ProtoReader r(overlong); + ProtoReader::Field f; + while (r.next(f)) { + } + ok = false; + } catch (const std::exception&) { + } + check(ok, "proto reader rejects an overlong varint (no shift-overflow UB)"); + // 3. negative/short-buffer node tags and truncations throw cleanly. ok = true; for (const Bytes& bad : std::vector{{}, {0x00}, {0x00, 0xf8}, {0x00, 0xfe, 0x7f, 0xff, 0xff, 0xff}, diff --git a/taicpp/tools/san-whatsapp.sh b/taicpp/tools/san-whatsapp.sh new file mode 100755 index 0000000..abb111d --- /dev/null +++ b/taicpp/tools/san-whatsapp.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# san-whatsapp.sh: build and run the WhatsApp wire parsers under AddressSanitizer +# + UndefinedBehaviorSanitizer + _GLIBCXX_ASSERTIONS. This is the standing net +# for detz::wa's parsing layer: a malformed frame that overflows a length check, +# over-reads a buffer, or over-allocates a vector aborts here at the exact line, +# instead of slipping past a bounds check in a release build. Run it in CI and +# before any change to a parser (WaBinary, WaProto, WaNoise, WaSignal). See +# docs/cpp-safety.md. +# +# The vendored ed25519 ref10 (third_party/ed25519) is built WITHOUT UBSan on +# purpose: it uses intentional, portable signed-shift idioms that UBSan flags +# but that are not bugs. Everything we wrote is fully sanitized. +set -euo pipefail +cd "$(dirname "$0")/.." +OUT=$(mktemp -d) +trap 'rm -rf "$OUT"' EXIT +SAN="-fsanitize=address,undefined -fno-sanitize-recover=all -D_GLIBCXX_ASSERTIONS -g -O1 -std=c++23 -Wall -Wextra" +INC="-Isrc/whatsapp -Isrc/llm -Ithird_party/ed25519" +# only the parser TUs the hostile/golden test exercises +for f in wa_crypto wa_binary wa_proto wa_noise wa_signal wa_device; do + g++ $SAN $INC -c "src/whatsapp/$f.cpp" -o "$OUT/$f.o" +done +g++ $SAN $INC -c src/llm/json.cpp -o "$OUT/json.o" +# ref10 C without UBSan (intentional portable shift idioms), still ASan for memory +for f in third_party/ed25519/*.c; do + cc -fsanitize=address -D_GLIBCXX_ASSERTIONS -g -O2 -Ithird_party/ed25519 -c "$f" -o "$OUT/$(basename "$f" .c).o" +done +g++ $SAN $INC tests/whatsapp_test.cpp "$OUT"/*.o -lssl -lcrypto -lz -o "$OUT/whatsapp_test_san" +echo "running whatsapp_test under ASan+UBSan+_GLIBCXX_ASSERTIONS ..." +"$OUT/whatsapp_test_san" tests/whatsapp_data +echo "san-whatsapp: OK"