diff --git a/.github/codeql/extensions/rust-models/codeql-pack.yml b/.github/codeql/extensions/rust-models/codeql-pack.yml new file mode 100644 index 00000000..fa838cf7 --- /dev/null +++ b/.github/codeql/extensions/rust-models/codeql-pack.yml @@ -0,0 +1,9 @@ +# Repository-local CodeQL model pack. Code scanning picks up any pack under +# .github/codeql/extensions automatically, in default and advanced setup. +name: dekobon/big-code-analysis-rust-models +version: 0.0.1 +library: true +extensionTargets: + codeql/rust-all: "*" +dataExtensions: + - models/**/*.yml diff --git a/.github/codeql/extensions/rust-models/models/vcs.model.yml b/.github/codeql/extensions/rust-models/models/vcs.model.yml new file mode 100644 index 00000000..7755bad9 --- /dev/null +++ b/.github/codeql/extensions/rust-models/models/vcs.model.yml @@ -0,0 +1,17 @@ +# CodeQL's Rust taint tracking is field-insensitive on a struct: writing a +# tainted value into one field taints the whole value, and reading any field +# of a tainted value is tainted. Options carries both the parsed window +# lengths (integer constants, which rust/hard-coded-cryptographic-value treats +# as sources) and the HMAC author_hash_key, so every window constant was +# reported as a hard-coded HMAC key (alerts #799-#803). +# +# Excluding the field removes only that read shortcut. A store into +# author_hash_key followed by a read of it is ordinary field-sensitive value +# flow, so a literal really stored there should still be reported (reasoned +# from the taint-step definitions, not probed). +extensions: + - addsTo: + pack: codeql/rust-all + extensible: excludeFieldTaintStep + data: + - ["big_code_analysis::vcs::options::Options::author_hash_key"] diff --git a/CHANGELOG.md b/CHANGELOG.md index b0762a92..5acb9694 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1360,6 +1360,14 @@ for historical reference. complete a handshake. `rustls` is a dev-only transitive dependency here (`jsonschema` → `reqwest`), reached by no shipped code path; the bump keeps the `cargo-deny` advisories gate green. +- Cleared RUSTSEC-2026-0306 by moving `faster-hex` `0.10.0` → `0.10.1` + in the workspace lockfile. On x86 / x86_64 with AVX2, the safe + `faster_hex::hex_decode_unchecked` could read past the end of a short + `src` buffer. `faster-hex` ships in `bca` through `gix-hash`, which + calls only the length-checked `hex_decode` / `hex_encode`, so no + shipped code path reached the unsound function. `cargo-deny` missed + the advisory because its default `unsound` scope covers direct + dependencies only; `deny.toml` now sets `unsound = "all"`. ## [2.2.0] - 2026-08-29 diff --git a/Cargo.lock b/Cargo.lock index 64c10c77..ff72795e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1065,6 +1065,15 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06" +[[package]] +name = "defmt" +version = "0.3.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0963443817029b2024136fc4dd07a5107eb8f977eaf18fcd1fdeb11306b64ad" +dependencies = [ + "defmt 1.1.1", +] + [[package]] name = "defmt" version = "1.1.1" @@ -1245,10 +1254,12 @@ dependencies = [ [[package]] name = "faster-hex" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7223ae2d2f179b803433d9c830478527e92b8117eab39460edae7f1614d9fb73" +checksum = "04839bdf9d8c10f66806fad16b852fc72aab80873aebc3cb69d85b4fa41543ed" dependencies = [ + "autocfg", + "defmt 0.3.100", "heapless", "serde", ] @@ -2709,7 +2720,7 @@ version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc" dependencies = [ - "defmt", + "defmt 1.1.1", "jiff-core", "jiff-static", "jiff-tzdb-platform", @@ -2726,7 +2737,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" dependencies = [ - "defmt", + "defmt 1.1.1", ] [[package]] diff --git a/big-code-analysis-py/requirements/examples.txt b/big-code-analysis-py/requirements/examples.txt index b5829ca1..b3e0cc74 100644 --- a/big-code-analysis-py/requirements/examples.txt +++ b/big-code-analysis-py/requirements/examples.txt @@ -551,9 +551,9 @@ jupyter-lsp==2.3.1 ; python_full_version < '3.15' and sys_platform != 'emscripte --hash=sha256:71b954d834e85ff3096400554f2eefaf7fe37053036f9a782b0f7c5e42dadb81 \ --hash=sha256:fdf8a4aa7d85813976d6e29e95e6a2c8f752701f926f2715305249a3829805a6 # via jupyterlab -jupyter-server==2.20.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ - --hash=sha256:b5778ba337d8015a3dc2b80803ecdd5ac18d3797fddf61a50ea5fb472b4ebe14 \ - --hash=sha256:c3b67c93c471e947c18b5026f04f21614218adb706df8f48227d3ee8e0a7cdcc +jupyter-server==2.21.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:2a6467606af7dbae2e7e31640030025969e15db6a649eae334af90415dc71dca \ + --hash=sha256:a8960aa29263f6041283e97d4756b099fb49b767baab6371891ecb1bd40a63df # via # jupyter-lsp # jupyterlab @@ -564,9 +564,9 @@ jupyter-server-terminals==0.5.4 ; python_full_version < '3.15' and sys_platform --hash=sha256:55be353fc74a80bc7f3b20e6be50a55a61cd525626f578dcb66a5708e2007d14 \ --hash=sha256:bbda128ed41d0be9020349f9f1f2a4ab9952a73ed5f5ac9f1419794761fb87f5 # via jupyter-server -jupyterlab==4.6.3 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ - --hash=sha256:0a1ebc6567186f1eabd99536e94df7ed9e96d1e7c5ddf3e4406ae16e88abacb7 \ - --hash=sha256:2e3db6e3a12495ebd188276e985bf5ac502fbde3d1e8628819920210008de498 +jupyterlab==4.6.4 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:15b13f991d3985129c797eb84d9949eeb8b6615e14b444868e642411f2c418b2 \ + --hash=sha256:404f49b081819378524886c9db66dba57a5565981eff885830df1baba3a17df5 # via # jupyter # notebook @@ -815,9 +815,9 @@ nest-asyncio2==1.7.2 ; python_full_version < '3.15' and sys_platform != 'emscrip --hash=sha256:1921d70b92cc4612c374928d081552efb59b83d91b2b789d935c665fa01729a8 \ --hash=sha256:f5dfa702f3f81f6a03857e9a19e2ba578c0946a4ad417b4c50a24d7ba641fe01 # via ipykernel -notebook==7.6.2 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ - --hash=sha256:5fe9e09c335cb4b7de21627b860f77210e70e54b1fb1276ad942a4a7e1d858d3 \ - --hash=sha256:cc02b5f0bb972160cccfe44ad8a1a202036206ba3439469c514f03aefa9ae807 +notebook==7.6.3 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:ad7e0eb765fba836cd4a2ab0c7a3a26cde1d91665fbf6f533b6ae7b2de6d88d2 \ + --hash=sha256:e2c08e469c0ae20bb0b3214f0ab77e79653317a2f8e5b34c10361c66874a5b50 # via jupyter notebook-shim==0.2.4 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ --hash=sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef \ diff --git a/big-code-analysis-py/uv.lock b/big-code-analysis-py/uv.lock index c0b735ed..6d9f54cd 100644 --- a/big-code-analysis-py/uv.lock +++ b/big-code-analysis-py/uv.lock @@ -1115,7 +1115,7 @@ wheels = [ [[package]] name = "jupyter-server" -version = "2.20.0" +version = "2.21.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -1137,9 +1137,9 @@ dependencies = [ { name = "traitlets" }, { name = "websocket-client" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6b/dc/db3a582633170186f8c8b31298d7eb26ad0eb031a1f53476c258b64eed05/jupyter_server-2.20.0.tar.gz", hash = "sha256:b5778ba337d8015a3dc2b80803ecdd5ac18d3797fddf61a50ea5fb472b4ebe14", size = 756523, upload-time = "2026-06-17T12:09:09.435Z" } +sdist = { url = "https://files.pythonhosted.org/packages/65/3d/3c9f8bce5d5448107bd285cd80185e76c9c871d076b580dfd90997e52904/jupyter_server-2.21.1.tar.gz", hash = "sha256:a8960aa29263f6041283e97d4756b099fb49b767baab6371891ecb1bd40a63df", size = 761651, upload-time = "2026-09-15T16:00:07.853Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f3/71/8c002223e873a870f5c41dc69b0a7c922301123e4a31d5d01ecb700aef77/jupyter_server-2.20.0-py3-none-any.whl", hash = "sha256:c3b67c93c471e947c18b5026f04f21614218adb706df8f48227d3ee8e0a7cdcc", size = 393143, upload-time = "2026-06-17T12:09:07.234Z" }, + { url = "https://files.pythonhosted.org/packages/1d/39/91bc08650cc8e3efeb7a83c25e20ebddcc9b70d28b4eb6f51a4fb55da7a4/jupyter_server-2.21.1-py3-none-any.whl", hash = "sha256:2a6467606af7dbae2e7e31640030025969e15db6a649eae334af90415dc71dca", size = 394641, upload-time = "2026-09-15T16:00:05.526Z" }, ] [[package]] @@ -1157,7 +1157,7 @@ wheels = [ [[package]] name = "jupyterlab" -version = "4.6.3" +version = "4.6.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "async-lru" }, @@ -1174,9 +1174,9 @@ dependencies = [ { name = "tornado" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/00/c0/45934229995d4c6e38192ca118d93185f60808f64157e3df3c5c28f8c5fd/jupyterlab-4.6.3.tar.gz", hash = "sha256:2e3db6e3a12495ebd188276e985bf5ac502fbde3d1e8628819920210008de498", size = 28319771, upload-time = "2026-08-10T18:50:57.947Z" } +sdist = { url = "https://files.pythonhosted.org/packages/33/8d/995cc142f6083346b35e7d3eadc5a6717ee89ce64ea53577010ac493bc3c/jupyterlab-4.6.4.tar.gz", hash = "sha256:404f49b081819378524886c9db66dba57a5565981eff885830df1baba3a17df5", size = 28335647, upload-time = "2026-09-21T15:25:18.779Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/47/242f46de028074651c9bd6d8000fc340ed0d3cdd1a0eae4387826123413a/jupyterlab-4.6.3-py3-none-any.whl", hash = "sha256:0a1ebc6567186f1eabd99536e94df7ed9e96d1e7c5ddf3e4406ae16e88abacb7", size = 17168312, upload-time = "2026-08-10T18:50:53.044Z" }, + { url = "https://files.pythonhosted.org/packages/3b/e4/072bc0d3c6d45d414062a06af7ee81c02a2c12d769c358ec9919f9995ffd/jupyterlab-4.6.4-py3-none-any.whl", hash = "sha256:15b13f991d3985129c797eb84d9949eeb8b6615e14b444868e642411f2c418b2", size = 17171596, upload-time = "2026-09-21T15:25:14.123Z" }, ] [[package]] @@ -1708,7 +1708,7 @@ wheels = [ [[package]] name = "notebook" -version = "7.6.2" +version = "7.6.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jupyter-builder" }, @@ -1718,9 +1718,9 @@ dependencies = [ { name = "notebook-shim" }, { name = "tornado" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/31/d9/5c76de84e96e1cf8aae3fce930875e0615e14f3557bbcdb634aab52da9d3/notebook-7.6.2.tar.gz", hash = "sha256:cc02b5f0bb972160cccfe44ad8a1a202036206ba3439469c514f03aefa9ae807", size = 5500147, upload-time = "2026-08-11T13:21:16.632Z" } +sdist = { url = "https://files.pythonhosted.org/packages/42/ac/aedb759dc683dcd129f6c75271bab5eb23020b0f7969163c726343718e1e/notebook-7.6.3.tar.gz", hash = "sha256:e2c08e469c0ae20bb0b3214f0ab77e79653317a2f8e5b34c10361c66874a5b50", size = 5501618, upload-time = "2026-09-21T18:07:24.261Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/fd/3e552ff5b24dd305c6e9a10e8645e29c03091c317429f326ae10dbae1ac6/notebook-7.6.2-py3-none-any.whl", hash = "sha256:5fe9e09c335cb4b7de21627b860f77210e70e54b1fb1276ad942a4a7e1d858d3", size = 5547102, upload-time = "2026-08-11T13:21:13.302Z" }, + { url = "https://files.pythonhosted.org/packages/a1/f7/907b98438cf00bdc4e296570058f29a347214bb42338a48e3b7eae58ae2a/notebook-7.6.3-py3-none-any.whl", hash = "sha256:ad7e0eb765fba836cd4a2ab0c7a3a26cde1d91665fbf6f533b6ae7b2de6d88d2", size = 5548452, upload-time = "2026-09-21T18:07:21.563Z" }, ] [[package]] diff --git a/deny.toml b/deny.toml index 97302867..1c66be84 100644 --- a/deny.toml +++ b/deny.toml @@ -11,6 +11,11 @@ all-features = true version = 2 yanked = "deny" ignore = [] +# The default scope ("workspace") reports an unsound advisory only for a +# direct dependency, so RUSTSEC-2026-0306 in `faster-hex` (reached through +# gix-hash) passed this gate for weeks and surfaced only via the Scorecard +# Vulnerabilities check. Unsound code anywhere in the graph ships in `bca`. +unsound = "all" [licenses] version = 2 diff --git a/src/vcs/options.rs b/src/vcs/options.rs index a7a0cfbb..d2ded164 100644 --- a/src/vcs/options.rs +++ b/src/vcs/options.rs @@ -231,6 +231,10 @@ pub struct Options { /// itself), so it never enters the persistent-cache fingerprint: the /// same cached walk re-finalizes under any key without a re-walk (see /// [`AuthorId::emit_hashed`](super::identity::AuthorId::emit_hashed)). + // + // Named by path in .github/codeql/extensions/rust-models: a rename or + // move must update that model, or CodeQL again reports every window + // constant as a hard-coded HMAC key (alerts #799-#803). pub author_hash_key: Option, /// Emit stats for files deleted at the target ref (default: off). pub include_deleted: bool,