From 0a5b3e0b097771310c3460f8c156db55fab5e0d2 Mon Sep 17 00:00:00 2001 From: Cristi Bleotiu Date: Thu, 3 Sep 2026 12:36:41 +0300 Subject: [PATCH] fix: bound Thrift compact varint reads What changed: - backport Apache Thrift's 10-byte compact varint limit and add boundary regressions - pin the patch in provenance and record the fixed CVE in OpenVEX Why: - current Trivy data flags CVE-2026-43871 in the vendored Thrift v0.23.0 module --- Dockerfile | 1 + RATIO1_PATCHES.md | 6 +++ SECURITY.md | 8 +++ .../thrift/lib/go/thrift/compact_protocol.go | 12 +++-- .../lib/go/thrift/compact_protocol_r1_test.go | 49 +++++++++++++++++++ scripts/verify-provenance.py | 7 ++- scripts/verify-security-vex.py | 48 +++++++++++++++++- security/openvex.json | 22 +++++++-- source/license-inventory.json | 8 ++- source/manifest.sha256 | 21 ++++---- source/ratio1-engine-overrides.json | 19 +++++++ tests/test_release_contract.py | 5 +- 12 files changed, 184 insertions(+), 22 deletions(-) create mode 100644 engine/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol_r1_test.go diff --git a/Dockerfile b/Dockerfile index 9e75ab3d..8bec17df 100644 --- a/Dockerfile +++ b/Dockerfile @@ -99,6 +99,7 @@ RUN --mount=from=cloudflared-builder,source=/cloudflared,target=/cloudflared,ro RUN --mount=type=cache,target=/root/.cache/go-build \ cd /workspace/engine \ && go test -mod=vendor \ + github.com/apache/thrift/lib/go/thrift \ github.com/jackc/pgproto3/v2 \ github.com/jackc/pgx/v4/internal/sanitize \ google.golang.org/grpc/internal/transport \ diff --git a/RATIO1_PATCHES.md b/RATIO1_PATCHES.md index 45521961..039e9c36 100644 --- a/RATIO1_PATCHES.md +++ b/RATIO1_PATCHES.md @@ -157,6 +157,12 @@ non-cancellable contexts. recognizes PostgreSQL dollar-quoted strings and clamps overflowing placeholders. `sanitize_r1_test.go` covers both cases; the backport follows upstream fix commit `60644f84918a8af66d14a4b0d865d4edafd955da`. +- `CVE-2026-43871`: + `engine/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol.go` + rejects compact-protocol varints longer than the valid 10-byte encoding for + a 64-bit integer. `compact_protocol_r1_test.go` covers the overlong input and + valid 10-byte boundary; the backport is the exact Go fix from Apache Thrift + commit `d5152211af61f850ec393604316804096dd4632e`. - `CVE-2026-84304`: the official gRPC-Go receive-buffer compaction fix from commit `8cfeca0e1ee5ea0980dcc320e20240fa1079ec77` is backported to the engine's vendored v1.82.1 source and Cloudflared's vendored v1.83.0 source. The engine diff --git a/SECURITY.md b/SECURITY.md index accff253..b409f1ce 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -70,6 +70,14 @@ identifies the upstream module version, so the exact VEX decision is `fixed`; the patch and test hashes are enforced by `source/ratio1-engine-overrides.json`. +`CVE-2026-43871` / `GHSA-8wv5-x4w7-5gww` permits an unauthenticated remote +peer to cause unbounded compact-protocol varint reads in Apache Thrift Go +versions before v0.24.0. The engine's vendored v0.23.0 source contains the +official 10-byte bound from Apache Thrift commit +`d5152211af61f850ec393604316804096dd4632e`. The implementation preimage, +patched source, and boundary regressions are hash-pinned in +`source/ratio1-engine-overrides.json`, so the exact VEX decision is `fixed`. + `CVE-2026-84304` / `GHSA-vp52-pcj8-j9qc` permits unauthenticated HTTP/2 DATA frame fragmentation to retain excessive heap objects in gRPC-Go servers. The database engine embeds gRPC v1.82.1 and Cloudflared embeds v1.83.0, so both are diff --git a/engine/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol.go b/engine/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol.go index a5223d38..c52b10d3 100644 --- a/engine/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol.go +++ b/engine/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol.go @@ -1,3 +1,5 @@ +// Modified by Ratio1 in 2026; see RATIO1_PATCHES.md. + /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -766,23 +768,27 @@ func (p *TCompactProtocol) readVarint32() (int32, error) { return int32(v), err } +// maxVarint64Bytes is the maximum wire size of a varint-encoded 64-bit integer: +// ceil(64/7) = 10 bytes, matching the protobuf wire-format specification. +const maxVarint64Bytes = 10 + // Read an i64 from the wire as a proper varint. The MSB of each byte is set // if there is another byte to follow. This can read up to 10 bytes. func (p *TCompactProtocol) readVarint64() (int64, error) { shift := uint(0) result := int64(0) - for { + for rsize := 0; rsize < maxVarint64Bytes; rsize++ { b, err := p.readByteDirect() if err != nil { return 0, err } result |= int64(b&0x7f) << shift if (b & 0x80) != 0x80 { - break + return result, nil } shift += 7 } - return result, nil + return 0, NewTProtocolExceptionWithType(INVALID_DATA, errors.New("variable-length int over 10 bytes")) } // Read a byte, unlike ReadByte that reads Thrift-byte that is i8. diff --git a/engine/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol_r1_test.go b/engine/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol_r1_test.go new file mode 100644 index 00000000..ea28f55a --- /dev/null +++ b/engine/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol_r1_test.go @@ -0,0 +1,49 @@ +// Copyright 2026 Ratio1 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package thrift + +import ( + "bytes" + "context" + "errors" + "testing" +) + +func TestRatio1CompactProtocolRejectsOverlongVarint(t *testing.T) { + payload := bytes.Repeat([]byte{0x80}, 11) + transport := NewTMemoryBufferLen(len(payload)) + _, _ = transport.Write(payload) + protocol := NewTCompactProtocol(transport) + + _, err := protocol.ReadI64(context.Background()) + var protocolErr TProtocolException + if !errors.As(err, &protocolErr) || protocolErr.TypeId() != INVALID_DATA { + t.Fatalf("overlong varint error = %v, want INVALID_DATA protocol error", err) + } + if got, want := transport.Len(), 1; got != want { + t.Fatalf("unread payload bytes = %d, want %d", got, want) + } +} + +func TestRatio1CompactProtocolAcceptsValidTenByteVarint(t *testing.T) { + payload := append(bytes.Repeat([]byte{0x80}, 9), 0x01) + transport := NewTMemoryBufferLen(len(payload)) + _, _ = transport.Write(payload) + protocol := NewTCompactProtocol(transport) + + if _, err := protocol.ReadI64(context.Background()); err != nil { + t.Fatalf("valid ten-byte varint was rejected: %v", err) + } +} diff --git a/scripts/verify-provenance.py b/scripts/verify-provenance.py index 3d874f73..ea47ee7b 100755 --- a/scripts/verify-provenance.py +++ b/scripts/verify-provenance.py @@ -59,7 +59,12 @@ "engine/pkg/util/goschedstats/runtime_go1.26.go", "engine/pkg/util/goschedstats/runtime_go1.26_test.go", } -EXPECTED_SECURITY_BACKPORTS = {"CVE-2026-84304", "GO-2026-4518", "GO-2026-5004"} +EXPECTED_SECURITY_BACKPORTS = { + "CVE-2026-43871", + "CVE-2026-84304", + "GO-2026-4518", + "GO-2026-5004", +} EXPECTED_COMPATIBILITY_BACKPORTS = {"google-api-grpc-credentials-options"} MIN_RETAINED_UPSTREAM_PACKAGE_FILES = 3000 MODIFICATION_NOTICE = b"Modified by Ratio1 in 2026; see RATIO1_PATCHES.md." diff --git a/scripts/verify-security-vex.py b/scripts/verify-security-vex.py index 180d697b..059f6a0b 100644 --- a/scripts/verify-security-vex.py +++ b/scripts/verify-security-vex.py @@ -18,6 +18,7 @@ "v1.8.2-0.20210914090109-37468d88dce8" ) PGPROTO_PURL = "pkg:golang/github.com/jackc/pgproto3/v2@v2.3.3" +THRIFT_PURL = "pkg:golang/github.com/apache/thrift@v0.23.0" UTIL_LINUX_PURL = ( "pkg:deb/debian/util-linux@2.38.1-5%2Bdeb12u3?" "arch=amd64&distro=debian-12.15" @@ -31,6 +32,7 @@ EXPECTED = { "CVE-2026-42154": (PROMETHEUS_PURL, "not_affected", "vulnerable_code_not_in_execute_path"), "CVE-2026-32286": (PGPROTO_PURL, "fixed", None), + "CVE-2026-43871": (THRIFT_PURL, "fixed", None), "CVE-2026-84304": ((GRPC_ENGINE_PURL, GRPC_CLOUDFLARED_PURL), "fixed", None), "CVE-2026-53615": (UTIL_LINUX_PURL, "not_affected", "vulnerable_code_not_present"), "CVE-2026-53613": (UTIL_LINUX_PURL, "not_affected", "vulnerable_code_not_present"), @@ -38,6 +40,7 @@ "CVE-2026-56854": (X_CRYPTO_PURL, "not_affected", "vulnerable_code_not_in_execute_path"), } REQUIRED_ALIASES = { + "CVE-2026-43871": {"CVE-2026-43871", "GHSA-8wv5-x4w7-5gww"}, "CVE-2026-84304": {"CVE-2026-84304", "GHSA-vp52-pcj8-j9qc"}, "CVE-2026-56854": {"CVE-2026-56854", "GO-2026-6303"}, } @@ -103,6 +106,46 @@ def verify_pgproto_backport() -> None: fail(f"pgproto3 regression evidence is absent: {evidence}") +def verify_thrift_backport() -> None: + overrides = json.loads((ROOT / "source/ratio1-engine-overrides.json").read_text(encoding="utf-8")) + records = [ + item for item in overrides["securityBackports"] + if item["advisory"] == "CVE-2026-43871" + ] + if len(records) != 1 or records[0].get("module") != "github.com/apache/thrift@v0.23.0": + fail("Apache Thrift backport metadata differs from the VEX product") + if len(records[0].get("files", [])) != 2: + fail("Apache Thrift backport file set is incomplete") + for file_record in records[0]["files"]: + path = ROOT / file_record["path"] + if not path.is_file() or sha256(path) != file_record.get("sha256"): + fail(f"Apache Thrift backport hash differs: {file_record.get('path')}") + + modules = (ROOT / "engine/vendor/modules.txt").read_text(encoding="utf-8") + if "# github.com/apache/thrift v0.23.0\n" not in modules: + fail("Apache Thrift version differs from the VEX product") + implementation = ( + ROOT / "engine/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol.go" + ).read_text(encoding="utf-8") + for marker in ( + "const maxVarint64Bytes = 10", + "for rsize := 0; rsize < maxVarint64Bytes; rsize++", + 'errors.New("variable-length int over 10 bytes")', + ): + if marker not in implementation: + fail(f"Apache Thrift varint backport evidence is absent: {marker}") + tests = ( + ROOT / "engine/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol_r1_test.go" + ).read_text(encoding="utf-8") + for marker in ( + "TestRatio1CompactProtocolRejectsOverlongVarint", + "TestRatio1CompactProtocolAcceptsValidTenByteVarint", + "transport.Len(), 1", + ): + if marker not in tests: + fail(f"Apache Thrift backport regression evidence is absent: {marker}") + + def verify_grpc_backport() -> None: overrides = json.loads((ROOT / "source/ratio1-engine-overrides.json").read_text(encoding="utf-8")) records = [ @@ -240,9 +283,9 @@ def main() -> None: document = json.loads(VEX.read_text(encoding="utf-8")) if document.get("@context") != "https://openvex.dev/ns/v0.2.0": fail("unexpected OpenVEX context") - if document.get("@id") != "https://github.com/Ratio1/r1-meshdb/security/vex/5": + if document.get("@id") != "https://github.com/Ratio1/r1-meshdb/security/vex/6": fail("unexpected OpenVEX document identity") - if document.get("version") != 5 or document.get("timestamp") != "2026-09-02T00:00:00Z": + if document.get("version") != 6 or document.get("timestamp") != "2026-09-03T00:00:00Z": fail("unexpected OpenVEX document version or timestamp") statements = document.get("statements") if not isinstance(statements, list) or len(statements) != len(EXPECTED): @@ -253,6 +296,7 @@ def main() -> None: verify_prometheus() verify_pgproto_backport() + verify_thrift_backport() verify_grpc_backport() verify_minimal_runtime() verify_ssh_server_authentication_absence() diff --git a/security/openvex.json b/security/openvex.json index 7a8e0eba..4b92d0b3 100644 --- a/security/openvex.json +++ b/security/openvex.json @@ -1,10 +1,10 @@ { "@context": "https://openvex.dev/ns/v0.2.0", - "@id": "https://github.com/Ratio1/r1-meshdb/security/vex/5", + "@id": "https://github.com/Ratio1/r1-meshdb/security/vex/6", "author": "Ratio1", "role": "Project Maintainer", - "timestamp": "2026-09-02T00:00:00Z", - "version": 5, + "timestamp": "2026-09-03T00:00:00Z", + "version": 6, "statements": [ { "vulnerability": { @@ -41,6 +41,22 @@ "status": "fixed", "status_notes": "Ratio1 backports the maintained negative DataRow field-length check from pgx commit 7f382f5190f58c16f5bd9d60f4443b658a5a3a22. The patched source and direct plus full-frame regressions are hash-pinned in source/ratio1-engine-overrides.json." }, + { + "vulnerability": { + "@id": "https://nvd.nist.gov/vuln/detail/CVE-2026-43871", + "aliases": [ + "CVE-2026-43871", + "GHSA-8wv5-x4w7-5gww" + ] + }, + "products": [ + { + "@id": "pkg:golang/github.com/apache/thrift@v0.23.0" + } + ], + "status": "fixed", + "status_notes": "Ratio1 backports the official Apache Thrift Go compact-protocol varint bound from commit d5152211af61f850ec393604316804096dd4632e. Exact implementation preimage, patched source, and boundary regression hashes are enforced by source/ratio1-engine-overrides.json." + }, { "vulnerability": { "@id": "https://nvd.nist.gov/vuln/detail/CVE-2026-84304", diff --git a/source/license-inventory.json b/source/license-inventory.json index fa65d6cf..acbf7009 100644 --- a/source/license-inventory.json +++ b/source/license-inventory.json @@ -38769,7 +38769,13 @@ { "basis": "engine/vendor/github.com/apache/thrift/LICENSE", "path": "engine/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol.go", - "sha256": "3a703697f986dd339b7a2cdfa31c117dfbf553431e1847c4c01175eb2d66fbe4", + "sha256": "d2784d15f4f9e57510b30f9bc3d5424f895dd7f0db050138985b3550a7c097ec", + "spdx": "Apache-2.0" + }, + { + "basis": "engine/vendor/github.com/apache/thrift/LICENSE", + "path": "engine/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol_r1_test.go", + "sha256": "a41d68c6ddc3c7839bb586af8604b772c8bfdbff4ae9ae7531e8bcd842d290a8", "spdx": "Apache-2.0" }, { diff --git a/source/manifest.sha256 b/source/manifest.sha256 index 7f4910a6..7cf9cf94 100644 --- a/source/manifest.sha256 +++ b/source/manifest.sha256 @@ -5,14 +5,14 @@ ac5cac0e73220dc824c9a07200444f392cd82b64c46c669c299d8d77e18662ec .github/workfl c20d5ca3853bca686890e4d959c945db76d8013e91d6106a6241f031a1a8aac0 .github/workflows/release.yml 5f2507148965114df76e05ddecb25ea419400fd9f655d71dd7d13eee226a51bd .github/workflows/security.yml 696452e46b8506219542eb7135c99419725055c59bd15e00e610d567d3a67ac6 .gitignore -160e8b2544e5ec4cdccc8cbf1481deafa250fc52a10a02f6bc58719286bebc48 Dockerfile +15f5fec5b2d7a288b2d7d8c9f2d868e0edf1ad6ba553e947bb2b69aade21b085 Dockerfile 24f9c32c2d3b165c1f9eb4a8aa2c582412a06b3c0c4630f9c77c4f5a6c3937e5 LICENSE 3b6f0ea03562d9a53a5dec4368f3fcbf430838864b013b621ccf073bbf9bb491 LICENSE-OVERVIEW.md 9f5fb5115fa01cca145ce84aff62b18dce1b82aa2669e8baedfbd97aed42eece NOTICE -ffcbec0e19d36cd75491523ec7eedd3a925e8cbf90dc9e1018efba91a9172631 RATIO1_PATCHES.md +68a326afbd1bcee02b0231478872ded838537f073b28feb740f1b07bed73360f RATIO1_PATCHES.md 2d75ebbd0369485a2b02fce6bcc6e39470b7e74a8b8a35877178555a75fd1258 README.md da4d2d3a41060a13be1793f45db842f59f21bc3b3cde6c7dd6a5a4a4dc1b318d RELEASE.md -cc5eac6a7617fd4f34c736dc61dc16eb1be0c48cc98badd9f70010f418cb6827 SECURITY.md +69c0bd037378cac54761147fcf7325c2715ad51077c5278d67a024678329e91d SECURITY.md aeecf7c915eaf76e40f6300914882f549e9197834c9c5adc8dfd1f3ab7f510a6 THIRD_PARTY_NOTICES.md 39a1ee86d8fbafc075c6d2a9d458357981b77e65635316dce3da7308ecc844e0 UPSTREAM.md 44e161e4495cac2cf7858043e9e6418e9579f0ddcfae826f9a372622968ce066 VERSION @@ -6477,7 +6477,8 @@ f7442db6db6bb00e8c0f3d144159ce913daacbff0662d90e7f22e89c354db401 engine/vendor/ 6539a6c2ebe89ddaed52380ff2bf88ae8a0229b94cab4ab3295b08e46a509957 engine/vendor/github.com/apache/thrift/lib/go/thrift/binary_protocol.go b64b576b627dbb52fca60f4984ab3a5f65d34d7f91a97e3fc125b766174918bf engine/vendor/github.com/apache/thrift/lib/go/thrift/buffered_transport.go ffb7ac3daf852297146e7d622c57e088b9ae8afec6f0f1070c8f9054a7439933 engine/vendor/github.com/apache/thrift/lib/go/thrift/client.go -3a703697f986dd339b7a2cdfa31c117dfbf553431e1847c4c01175eb2d66fbe4 engine/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol.go +d2784d15f4f9e57510b30f9bc3d5424f895dd7f0db050138985b3550a7c097ec engine/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol.go +a41d68c6ddc3c7839bb586af8604b772c8bfdbff4ae9ae7531e8bcd842d290a8 engine/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol_r1_test.go d7f62ea8f78b391faf72e8d6a6c1f832794bb7485c8546f37dc9266e5aef4422 engine/vendor/github.com/apache/thrift/lib/go/thrift/configuration.go 460e8631b6e71e6c2ae3854fc9c864db999bc94edff808f238c04f91347ef8fd engine/vendor/github.com/apache/thrift/lib/go/thrift/context.go 6daf828af15cb0ec7494359a1997b1e7c5f7649720b0e0407f37cbdd757ce1cb engine/vendor/github.com/apache/thrift/lib/go/thrift/debug_protocol.go @@ -12101,27 +12102,27 @@ aceccd97e9865dff8dd84137f5d8359949cf6d4cdc3199987c9a4e3990f24f2b scripts/store- 88882da5bf030bcbbd0daa034366da74122870e4dc92430a2f4da3658aa3637c scripts/verify-cloudflared-source.py cf97006d7eb1324c8ae7213f254eafafe3887c8055c11a96cd6ed07c86b1599c scripts/verify-generated-provenance.py dff91cbe165fefadab40161cbbc06d1d232a8092d6e31f78cb9e33d26ca6a278 scripts/verify-image.sh -d113a777fbabfa6024f99832b250ddf748da540cd4c0ccbe4b60c81c37674eb4 scripts/verify-provenance.py +bac365005ed60cc452e9527bc88f6dd6bb739f1ef1a11ff582b57b6b785b1b48 scripts/verify-provenance.py 41a3d3bc669d6fcd6faed578fabe56b3f0e395447b6c4702842f92beb6eed380 scripts/verify-public-test-fixtures.py 3c7d65f185259095487e33113e58c509c22988ba4f10b9537d1e0b499e4ad75e scripts/verify-runtime-closure.py 205776262119fab936cf1864826d4a83dc3e53d95e375e7c453d2c5e6b32a193 scripts/verify-sbom.py -d30d252904951c387e3cfa6082d8274d1ee47092412a3419653ac63c9307b901 scripts/verify-security-vex.py +0680542cdc69c22af9601317ef1124587b8bc1af51ea695da43ff254bc5a644b scripts/verify-security-vex.py e1e02a95c6cf4f0a28e613d39cc303e2c5ceac9ea83535b7cb20a46e408253bd scripts/verify-source-boundary.py 452fe4191ad30a2eb15b9de04cf30b4b91015b7fb169cceaec15492d94c25101 scripts/verify-upstream-provenance.sh 0add13007694c5ac630a4311e65e797daee726ba82589ea8991564e209faf019 scripts/verify-vendor-provenance.go d684f3115ea45a133ab9f1fa0202fbadfd86bc599d212ad81125f69d9a498f42 scripts/verify_cloudflared_ssh_usage.go 6c9cb144578bc94070ad7ebb6b90c8361390d8b34171eb7388c8db76ba321f36 scripts/verify_cloudflared_ssh_usage_test.go c98442d4f6badbb1b0adcfa79dc28478eb105d1cdbad4ca232c85f4a3c653043 security/backports/grpc-go-cve-2026-84304-v1.83.0.patch -779690f78142e6706d211b41f3b399d2ce5955f7ea16db339c1e61205deba371 security/openvex.json +2f50a4c1434bb041c491994cdb3172fd23da60a85c9f9dd5cfe7d5537688f8cb security/openvex.json ad4e90969340d12b88b835418aff3f1235fd02bec5d745a24ff94959621cc23e source/cloudflared-buildinfo.txt e9bbbf63fd90e29f7c1922ffec04b800ace20b3c3cbd284c2ee9a58f511b49e9 source/cloudflared-compiled-packages.txt e9f1ede5da65e8036fe18e487d48e3068f311810d6af156e36943823d54a85c9 source/cloudflared-license-inventory.csv ba79d5d4e92b21bfe85aa1aa23615088800fd06dca09e0ddcd1ba782b4990c12 source/engine-v23.1.28-vendor-modules.baseline.txt 5387d5a3000e560fac3a9de67bde7d6b033d12e6eabb429ab847eb03be17b757 source/generated-files.txt -4c35f78aea2aaa86b04b4fdfb385f4dc1fef06c96a312d458c8d14ea73e9d31b source/license-inventory.json +9e9a8371cd08af31eddbe335932dc09a394adf25798551ba45d8efb6d52d026d source/license-inventory.json b061c2122490248e8a1945266008405e237e63e4b0457e64b6f079ba50de54a7 source/provenance.json c85a936b214703fa0fb2af43e8f833fa665f2a597ea60d0a9a51546e08477f03 source/public-test-fixtures.sha256 -f8e6e663cbb89656a8cbbbdb12e049bd3290cf51e4e7fb4de575b502c9d66136 source/ratio1-engine-overrides.json +237fce22046e8794eb6cbe80e2a434b3aa0f5fa44351bb25fac6e7a1bd1650ac source/ratio1-engine-overrides.json c2100b615d71fd00b6a9af18ff7ef86fb623929cd65867a95f38595ded5e859d source/runtime-files.txt 77624d779e7cb9293643574cfdfcf95fd1fb1e8e441120262258408109b18aa9 source/runtime-package-sources.tsv 991e35c46975c578c58dc9fd1f6b0b96507afdc2b39c4e42acf9774993ee2aeb source/runtime-packages.txt @@ -12146,5 +12147,5 @@ c7bacb9dffc56a0411b55022538de645e5fa8fb18455e397d782366a9d371114 tests/runtime- 8e321ca8065577c96f3dfa35c96deb21771a001c76775ac2ecc7295a316ad2a3 tests/runtime-supervision/tail-test-stub.sh 91b1138b515c45788533118b27f08efd49013e6e9806166580d6e14e2d8c0680 tests/test_cloudflare_cleanup_recovery.py 7be07ef767a2132c79ae431847edce048b935aae4fc5e71fc938005a16460a23 tests/test_cloudflare_ephemeral_tunnels.py -170db2c28a7c752ddc3219bea6aa3ece3d137e3a38ed9fb436b7b5f7c024e9d5 tests/test_release_contract.py +f22bad3926a71c12fa0e036b806887c499d121f5370b06c588c5f01459e344a3 tests/test_release_contract.py a52e62e437de00e1504c383419056e96cddf18b15a85e0053f63136184bb7722 tests/test_sbom_contract.py diff --git a/source/ratio1-engine-overrides.json b/source/ratio1-engine-overrides.json index d7e93c86..0af174f0 100644 --- a/source/ratio1-engine-overrides.json +++ b/source/ratio1-engine-overrides.json @@ -342,6 +342,25 @@ } ] }, + { + "module": "github.com/apache/thrift@v0.23.0", + "advisory": "CVE-2026-43871", + "source": "https://github.com/apache/thrift/commit/d5152211af61f850ec393604316804096dd4632e", + "preimageCommit": "38e4c896cab7a547b3be3df5ac203f3afcc38a6d", + "files": [ + { + "path": "engine/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol.go", + "changeType": "modified-upstream", + "preimageSha256": "3a703697f986dd339b7a2cdfa31c117dfbf553431e1847c4c01175eb2d66fbe4", + "sha256": "d2784d15f4f9e57510b30f9bc3d5424f895dd7f0db050138985b3550a7c097ec" + }, + { + "path": "engine/vendor/github.com/apache/thrift/lib/go/thrift/compact_protocol_r1_test.go", + "changeType": "ratio1-added", + "sha256": "a41d68c6ddc3c7839bb586af8604b772c8bfdbff4ae9ae7531e8bcd842d290a8" + } + ] + }, { "module": "google.golang.org/grpc@v1.82.1", "advisory": "CVE-2026-84304", diff --git a/tests/test_release_contract.py b/tests/test_release_contract.py index ad333370..13cd45c4 100755 --- a/tests/test_release_contract.py +++ b/tests/test_release_contract.py @@ -484,7 +484,7 @@ def test_repository_identity_is_r1_meshdb_everywhere(self): f'baseline_repository != "{source_url}.git"', read("scripts/verify-provenance.py"), ) - self.assertEqual(json.loads(read("security/openvex.json"))["@id"], f"{source_url}/security/vex/5") + self.assertEqual(json.loads(read("security/openvex.json"))["@id"], f"{source_url}/security/vex/6") self.assertEqual( json.loads(read("source/ratio1-engine-overrides.json"))["dependencySnapshot"] ["sourceBaseline"]["repository"], @@ -620,7 +620,7 @@ def test_source_provenance_pins_upstream_and_native_dependencies(self): ) self.assertEqual( {record["advisory"] for record in overrides["securityBackports"]}, - {"CVE-2026-84304", "GO-2026-4518", "GO-2026-5004"}, + {"CVE-2026-43871", "CVE-2026-84304", "GO-2026-4518", "GO-2026-5004"}, ) self.assertEqual( {record["id"] for record in overrides["dependencyCompatibilityBackports"]}, @@ -876,6 +876,7 @@ def test_release_build_uses_only_pinned_neutral_inputs(self): self.assertIn("scripts/build-engine.sh", dockerfile) self.assertIn("scripts/verify-provenance.py", dockerfile) self.assertIn("go test -mod=vendor", dockerfile) + self.assertIn("github.com/apache/thrift/lib/go/thrift", dockerfile) self.assertIn("github.com/jackc/pgproto3/v2", dockerfile) self.assertIn("github.com/jackc/pgx/v4/internal/sanitize", dockerfile) self.assertIn("google.golang.org/grpc/internal/transport", dockerfile)